// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_sg_plotter #define tools_sg_plotter #include "../lina/vec2f" #include "render_action" #include "plottables" #include "style" #include "rep" #include "colormap" #include "noderef" #include "atb_vertices" #include "cube" //for lego #include "matrix" #include "normal" #include "holder" #include "tex_rect" //for plottable_img. #include "axis" #include "infos_box" #include "legend" #include "text" #include "torche" #include "ellipse" #include "../data_axis" #include "../hatcher" #include "../clist_contour" #include "../tess_contour" #include "../lina/geom3" #include "../spline" #include "../rtausmef" //#define INLIBS_SG_PLOTTER_TIMING #ifdef INLIBS_SG_PLOTTER_TIMING #include "../sys/atime" #endif #include namespace tools { namespace sg { class plotter : public node { TOOLS_NODE(plotter,tools::sg::plotter,node) private: static const std::string& s_infos_what_def() { static const std::string s_v("name entries mean rms fit_quality fit_ndf fit_parameters fit_errors"); return s_v; } static float default_infos_margin() {return 0.005f;} static float default_title_box_width() {return 0.3f;} static float default_title_box_height() {return 0.05f;} static float default_title_box_x_margin() {return 0.01f;} static float default_title_box_y_margin() {return 0.005f;} public: sf width; //PAW XSIZ sf height; //PAW YSIZ sf left_margin; //PAW XMGL sf right_margin; //PAW XMGR sf bottom_margin; //PAW YMGL sf top_margin; //PAW YMGU sf depth; sf down_margin; sf up_margin; sf title_up; sf title_to_axis; sf title_height; sf title_automated; sf_enum title_hjust; sf_string title; //output if title_automated. sf colormap_visible; enum colormap_axis_labeling_type { cells = 0, min_max }; sf_enum colormap_axis_labeling; sf colormap_attached; sf colormap_axis_visible; // Wanted axes parameters. // They are not necessary realized on the sg::axis nodes. sf x_axis_enforced; sf x_axis_automated; sf x_axis_min; sf x_axis_max; sf x_axis_is_log; sf y_axis_enforced; sf y_axis_automated; sf y_axis_min; sf y_axis_max; sf y_axis_is_log; sf z_axis_enforced; sf z_axis_automated; sf z_axis_min; sf z_axis_max; sf z_axis_is_log; sf value_top_margin; sf value_bottom_margin; sf value_bins_with_entries; sf infos_width; //in percent of width. sf infos_x_margin; //in percent of width. From right. sf infos_y_margin; //in percent of height. From top. sf_string infos_what; sf title_box_width; //in percent of width. sf title_box_height; //in percent of height. sf title_box_x_margin; //in percent of width. From left. sf title_box_y_margin; //in percent of height. From top. sf func2D_borders_visible; // used with shape xyz sf theta; //in degrees. sf phi; //in degrees. sf tau; //in degrees. //////////////////////////////////////////////////////////////// /// legend related ://////////////////////////////////////////// //////////////////////////////////////////////////////////////// sf legends_automated; //sf legends_attached_to_infos; //if legends_attached_to_infos is false : // legends_origin is used to place the legends. It is then // the lower left corner of the box containing all legends. mf_vec legends_origin; //common origin of legend boxes. enum unit_type { unit_percent, unit_axis }; mf_enum legends_origin_unit; mf_vec legends_size; //overall legend boxes size. mf_string legends_string; //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// sf shape_automated; enum shape_type { xy = 0, xyz }; sf_enum shape; // used with xy shape : sf xy_depth; //all is in z [0,xy_depth] sf curve_number_of_points; sf data_light_on_automated; // for gopaw : sf primitives_enforced; sf inner_frame_enforced; // to be implemented : sf top_axis_visible; sf right_axis_visible; sf superpose_bins; //sf grid_visible; // For contours : sf number_of_levels; mf levels; //sf frozen; //sf ttfScale; //sf wallEnforced; //sf gridEnforced; //SoMFString infos; //Output //SoMFString legend; //Output public: virtual const desc_fields& node_desc_fields() const { TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::plotter) static const desc_fields s_v(parent::node_desc_fields(),63, //WARNING : take care of count. TOOLS_ARG_FIELD_DESC(width), TOOLS_ARG_FIELD_DESC(height), TOOLS_ARG_FIELD_DESC(left_margin), TOOLS_ARG_FIELD_DESC(right_margin), TOOLS_ARG_FIELD_DESC(bottom_margin), TOOLS_ARG_FIELD_DESC(top_margin), TOOLS_ARG_FIELD_DESC(depth), TOOLS_ARG_FIELD_DESC(down_margin), TOOLS_ARG_FIELD_DESC(up_margin), TOOLS_ARG_FIELD_DESC(colormap_visible), //10 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(colormap_axis_labeling,2) TOOLS_ARG_ENUM(cells), TOOLS_ARG_ENUM(min_max) TOOLS_ARG_FIELD_DESC_ENUMS_END, TOOLS_ARG_FIELD_DESC(colormap_attached), TOOLS_ARG_FIELD_DESC(colormap_axis_visible), TOOLS_ARG_FIELD_DESC(title_up), TOOLS_ARG_FIELD_DESC(title_to_axis), TOOLS_ARG_FIELD_DESC(title_height), TOOLS_ARG_FIELD_DESC(title_automated), TOOLS_ARG_FIELD_DESC_ENUMS_BEG(title_hjust,3) "left",left, "center",center, "right",right TOOLS_ARG_FIELD_DESC_ENUMS_END, TOOLS_ARG_FIELD_DESC(title), TOOLS_ARG_FIELD_DESC(x_axis_enforced), //20 TOOLS_ARG_FIELD_DESC(x_axis_automated), TOOLS_ARG_FIELD_DESC(x_axis_min), TOOLS_ARG_FIELD_DESC(x_axis_max), TOOLS_ARG_FIELD_DESC(x_axis_is_log), TOOLS_ARG_FIELD_DESC(y_axis_enforced), TOOLS_ARG_FIELD_DESC(y_axis_automated), TOOLS_ARG_FIELD_DESC(y_axis_min), TOOLS_ARG_FIELD_DESC(y_axis_max), TOOLS_ARG_FIELD_DESC(y_axis_is_log), TOOLS_ARG_FIELD_DESC(z_axis_enforced), //30 TOOLS_ARG_FIELD_DESC(z_axis_automated), TOOLS_ARG_FIELD_DESC(z_axis_min), TOOLS_ARG_FIELD_DESC(z_axis_max), TOOLS_ARG_FIELD_DESC(z_axis_is_log), TOOLS_ARG_FIELD_DESC(value_top_margin), TOOLS_ARG_FIELD_DESC(value_bottom_margin), TOOLS_ARG_FIELD_DESC(value_bins_with_entries), TOOLS_ARG_FIELD_DESC(infos_width), TOOLS_ARG_FIELD_DESC(infos_x_margin), TOOLS_ARG_FIELD_DESC(infos_y_margin), //40 TOOLS_ARG_FIELD_DESC(infos_what), TOOLS_ARG_FIELD_DESC(func2D_borders_visible), TOOLS_ARG_FIELD_DESC(theta), TOOLS_ARG_FIELD_DESC(phi), TOOLS_ARG_FIELD_DESC(tau), TOOLS_ARG_FIELD_DESC(legends_automated), TOOLS_ARG_FIELD_DESC_ENUMS_BEG(legends_origin,2) "unit_percent",unit_percent, "unit_axis",unit_axis TOOLS_ARG_FIELD_DESC_ENUMS_END, TOOLS_ARG_FIELD_DESC(legends_origin_unit), TOOLS_ARG_FIELD_DESC(legends_size), TOOLS_ARG_FIELD_DESC(legends_string), //50 TOOLS_ARG_FIELD_DESC(shape_automated), TOOLS_ARG_FIELD_DESC_ENUMS_BEG(shape,2) "xy",xy, "xyz",xyz TOOLS_ARG_FIELD_DESC_ENUMS_END, TOOLS_ARG_FIELD_DESC(xy_depth), TOOLS_ARG_FIELD_DESC(curve_number_of_points), TOOLS_ARG_FIELD_DESC(number_of_levels), TOOLS_ARG_FIELD_DESC(levels), TOOLS_ARG_FIELD_DESC(data_light_on_automated), TOOLS_ARG_FIELD_DESC(primitives_enforced), TOOLS_ARG_FIELD_DESC(inner_frame_enforced), TOOLS_ARG_FIELD_DESC(title_box_width), //60 TOOLS_ARG_FIELD_DESC(title_box_height), TOOLS_ARG_FIELD_DESC(title_box_x_margin), TOOLS_ARG_FIELD_DESC(title_box_y_margin) //63 ); return s_v; } virtual bool touched() { if(parent::touched()) return true; if(background_style().touched()) return true; if(title_style().touched()) return true; if(infos_style().touched()) return true; if(title_box_style().touched()) return true; if(inner_frame_style().touched()) return true; if(grid_style().touched()) return true; if(wall_style().touched()) return true; {tools_vforit(style,m_bins_style,it) {if((*it).touched()) return true;}} {tools_vforit(style,m_errors_style,it) {if((*it).touched()) return true;}} {tools_vforit(style,m_func_style,it) {if((*it).touched()) return true;}} {tools_vforit(style,m_points_style,it) {if((*it).touched()) return true;}} {tools_vforit(style,m_left_hatch_style,it) {if((*it).touched()) return true;}} {tools_vforit(style,m_right_hatch_style,it) {if((*it).touched()) return true;}} {tools_vforit(style,m_legend_style,it) {if((*it).touched()) return true;}} return false; } virtual void reset_touched() { parent::reset_touched(); background_style().reset_touched(); title_style().reset_touched(); infos_style().reset_touched(); title_box_style().reset_touched(); inner_frame_style().reset_touched(); grid_style().reset_touched(); wall_style().reset_touched(); {tools_vforit(style,m_bins_style,it) (*it).reset_touched();} {tools_vforit(style,m_errors_style,it) (*it).reset_touched();} {tools_vforit(style,m_func_style,it) (*it).reset_touched();} {tools_vforit(style,m_points_style,it) (*it).reset_touched();} {tools_vforit(style,m_left_hatch_style,it) (*it).reset_touched();} {tools_vforit(style,m_right_hatch_style,it) (*it).reset_touched();} {tools_vforit(style,m_legend_style,it) (*it).reset_touched();} } private: void add_fields(){ // if adding a field, look for reset_style(), set_from_style() and set_from_string() add_field(&width); add_field(&height); add_field(&left_margin); add_field(&right_margin); add_field(&bottom_margin); add_field(&top_margin); add_field(&depth); add_field(&down_margin); add_field(&up_margin); add_field(&title_up); add_field(&title_to_axis); add_field(&title_height); add_field(&title_automated); add_field(&title_hjust); add_field(&title); add_field(&x_axis_enforced); add_field(&x_axis_automated); add_field(&x_axis_min); add_field(&x_axis_max); add_field(&x_axis_is_log); add_field(&y_axis_enforced); add_field(&y_axis_automated); add_field(&y_axis_min); add_field(&y_axis_max); add_field(&y_axis_is_log); add_field(&z_axis_enforced); add_field(&z_axis_automated); add_field(&z_axis_min); add_field(&z_axis_max); add_field(&z_axis_is_log); add_field(&value_top_margin); add_field(&value_bottom_margin); add_field(&value_bins_with_entries); add_field(&infos_width); add_field(&infos_x_margin); add_field(&infos_y_margin); add_field(&infos_what); add_field(&title_box_width); add_field(&title_box_height); add_field(&title_box_x_margin); add_field(&title_box_y_margin); add_field(&func2D_borders_visible); add_field(&theta); add_field(&phi); add_field(&tau); add_field(&legends_automated); //add_field(&legends_attached_to_infos); add_field(&legends_origin); add_field(&legends_origin_unit); add_field(&legends_size); add_field(&legends_string); add_field(&shape_automated); add_field(&shape); add_field(&xy_depth); add_field(&curve_number_of_points); add_field(&number_of_levels); add_field(&levels); add_field(&data_light_on_automated); add_field(&primitives_enforced); add_field(&inner_frame_enforced); } public: //style void copy_style(const plotter& a_from) { //used in sg::plots. //////////////////////////////////////////// //////////////////////////////////////////// //////////////////////////////////////////// shape_automated = a_from.shape_automated; shape = a_from.shape; xy_depth = a_from.xy_depth; curve_number_of_points = a_from.curve_number_of_points; value_top_margin = a_from.value_top_margin; value_bottom_margin = a_from.value_bottom_margin; value_bins_with_entries = a_from.value_bins_with_entries; infos_what = a_from.infos_what; infos_width = a_from.infos_width; //infos height is automatic. infos_x_margin = a_from.infos_x_margin; infos_y_margin = a_from.infos_y_margin; title_box_width = a_from.title_box_width; title_box_height = a_from.title_box_height; title_box_x_margin = a_from.title_box_x_margin; title_box_y_margin = a_from.title_box_y_margin; legends_automated = a_from.legends_automated; title_automated = a_from.title_automated; title = a_from.title; title_up = a_from.title_up; title_hjust = a_from.title_hjust; colormap_visible = a_from.colormap_visible; colormap_axis_labeling = a_from.colormap_axis_labeling; colormap_attached = a_from.colormap_attached; colormap_axis_visible = a_from.colormap_axis_visible; number_of_levels = a_from.number_of_levels; levels = a_from.levels; data_light_on_automated = a_from.data_light_on_automated; primitives_enforced = a_from.primitives_enforced; inner_frame_enforced = a_from.inner_frame_enforced; //////////////////////////////////////////// //////////////////////////////////////////// //////////////////////////////////////////// x_axis_enforced = a_from.x_axis_enforced; x_axis_automated = a_from.x_axis_automated; x_axis_min = a_from.x_axis_min; x_axis_max = a_from.x_axis_max; x_axis_is_log = a_from.x_axis_is_log; y_axis_enforced = a_from.y_axis_enforced; y_axis_automated = a_from.y_axis_automated; y_axis_min = a_from.y_axis_min; y_axis_max = a_from.y_axis_max; y_axis_is_log = a_from.y_axis_is_log; z_axis_enforced = a_from.z_axis_enforced; z_axis_automated = a_from.z_axis_automated; z_axis_min = a_from.z_axis_min; z_axis_max = a_from.z_axis_max; z_axis_is_log = a_from.z_axis_is_log; /* m_x_axis = a_from.m_x_axis; m_y_axis = a_from.m_y_axis; m_z_axis = a_from.m_z_axis; m_cmap_axis = a_from.m_cmap_axis; */ //////////////////////////////////////////// //////////////////////////////////////////// //////////////////////////////////////////// m_background_style = a_from.m_background_style; m_title_style = a_from.m_title_style; m_infos_style = a_from.m_infos_style; m_title_box_style = a_from.m_title_box_style; m_inner_frame_style = a_from.m_inner_frame_style; m_grid_style = a_from.m_grid_style; m_wall_style = a_from.m_wall_style; m_bins_style = a_from.m_bins_style; m_errors_style = a_from.m_errors_style; m_func_style = a_from.m_func_style; m_points_style = a_from.m_points_style; m_left_hatch_style = a_from.m_left_hatch_style; m_right_hatch_style = a_from.m_right_hatch_style; m_legend_style = a_from.m_legend_style; } void reset_style(bool a_geom = false) { //reset fields that are considered as part of the style. //::printf("debug : tools::sg::plotter::reset_style :\n"); shape_automated = true; shape = xy; xy_depth = 0.01f; curve_number_of_points = 100; //////////////////////////////////////////// value_top_margin = 0.1f; //percent. // CERN-PAW seems to have 0.1F and CERN-ROOT 0.05F. value_bottom_margin = 0.0f; //percent. value_bins_with_entries = true; //gopaw uses false. infos_what = s_infos_what_def(); infos_width = 0.3f; //infos height is automatic. infos_x_margin = default_infos_margin(); //percent of width infos_y_margin = default_infos_margin(); //percent of height title_box_width = default_title_box_width(); title_box_height = default_title_box_height(); title_box_x_margin = default_title_box_x_margin(); //percent of width title_box_y_margin = default_title_box_y_margin(); //percent of height legends_automated = true; //////////////////////////////////////////// if(a_geom) { float xfac = 1.0F/20.0F; //0.05 float yfac = 1.0F/20.0F; //0.05 // Take PAW defaults : float XSIZ = 20 * xfac; //1 //page width float YSIZ = 20 * yfac; //1 //page height float XMGL = 2 * xfac; //0.1 //left x margin (to data frame). float XMGR = 2 * xfac; //0.1 //right y margin (to data frame). float YMGL = 2 * yfac; //0.1 //low y margin (to data frame). float YMGU = 2 * yfac; //0.1 //up y margin (to data frame). // Axes : float VSIZ = 0.28F * yfac; //0.014 //tick label character size. float XVAL = 0.4F * xfac; //0.02 //x distance of y tick label to data frame. float YVAL = 0.4F * yfac; //0.02 //y distance of x tick label to data frame. float XTIC = 0.3F * yfac; //0.015 //y length of X axis ticks. float YTIC = 0.3F * xfac; //0.015 //x length of Y axis ticks. float XLAB = 1.4F * xfac; //0.07 //x distance of y title to data frame. float YLAB = 0.8F * yfac; //0.04 //y distance of x title to data frame. float ASIZ = 0.28F * yfac; //0.014 // axis title (label) character size. float YHTI = 1.2F * yfac; //0.06 //y distance of title to x axis. float TSIZ = 0.28F * yfac; //0.014 //title character size float zfac = 1.0F/20.0F; //0.05 float ZSIZ = 20 * zfac; //1 //page depth float ZMGD = 2 * zfac; //0.1 //low y margin (to data frame). float ZMGU = 2 * zfac; //0.1 //up y margin (to data frame). // Data area : //float wData = XSIZ-XMGL-XMGR; //float hData = YSIZ-YMGL-YMGU; //float dData = ZSIZ-ZMGD-ZMGU; width = XSIZ; height = YSIZ; depth = ZSIZ; left_margin = XMGL; right_margin = XMGR; bottom_margin = YMGL; top_margin = YMGU; down_margin = ZMGD; up_margin = ZMGU; title_to_axis = YHTI; title_height = TSIZ; if(shape.value()==xy) { m_x_axis.tick_length.value(XTIC); m_x_axis.label_to_axis.value(YVAL); m_x_axis.label_height.value(VSIZ); m_x_axis.title_to_axis.value(YLAB); m_x_axis.title_height.value(ASIZ); m_y_axis.tick_length.value(YTIC); m_y_axis.label_to_axis.value(XVAL); m_y_axis.label_height.value(VSIZ); m_y_axis.title_to_axis.value(XLAB); m_y_axis.title_height.value(ASIZ); //set anyway z axis : //m_z_axis.tick_length.value(YTIC); //m_z_axis.label_to_axis.value(XVAL); //m_z_axis.label_height.value(VSIZ); //m_z_axis.title_to_axis.value(XLAB); //m_z_axis.title_height.value(ASIZ); m_cmap_axis.tick_length.value(YTIC); m_cmap_axis.label_to_axis.value(XVAL); m_cmap_axis.label_height.value(VSIZ); m_cmap_axis.title_to_axis.value(XLAB); m_cmap_axis.title_height.value(ASIZ); } else { //xyz m_x_axis.tick_length.value(XTIC); m_x_axis.label_to_axis.value(YVAL); m_x_axis.label_height.value(VSIZ); m_x_axis.title_to_axis.value(YLAB); m_x_axis.title_height.value(ASIZ); m_y_axis.tick_length.value(XTIC); m_y_axis.label_to_axis.value(YVAL); m_y_axis.label_height.value(VSIZ); m_y_axis.title_to_axis.value(YLAB); m_y_axis.title_height.value(ASIZ); m_z_axis.tick_length.value(YTIC); m_z_axis.label_to_axis.value(XVAL); m_z_axis.label_height.value(VSIZ); m_z_axis.title_to_axis.value(XLAB); m_z_axis.title_height.value(ASIZ); m_cmap_axis.tick_length.value(XTIC); m_cmap_axis.label_to_axis.value(YVAL); m_cmap_axis.label_height.value(VSIZ); m_cmap_axis.title_to_axis.value(YLAB); m_cmap_axis.title_height.value(ASIZ); } } title_automated = true; title.value().clear(); title_up = true; title_hjust = center; //////////////////////////////////////////// colormap_visible = true; colormap_axis_labeling = cells; colormap_attached = true; colormap_axis_visible = true; //////////////////////////////////////////// x_axis_enforced = false; x_axis_automated = true; x_axis_min = 0; x_axis_max = 1; x_axis_is_log = false; y_axis_enforced = false; y_axis_automated = true; y_axis_min = 0; y_axis_max = 1; y_axis_is_log = false; z_axis_enforced = false; z_axis_automated = true; z_axis_min = 0; z_axis_max = 1; z_axis_is_log = false; m_x_axis.reset_style(); m_y_axis.reset_style(); m_z_axis.reset_style(); //////////////////////////////////////////// //////////////////////////////////////////// //////////////////////////////////////////// number_of_levels = 10; levels.clear(); data_light_on_automated = true; primitives_enforced = false; inner_frame_enforced = false; //////////////////////////////////////////// // setup styles : //////////////////////////////////////////// m_title_style = text_style(); m_infos_style = text_style(); m_title_box_style = text_style(); m_background_style = style(); m_wall_style = style(); m_inner_frame_style = style(); m_grid_style = style(); m_title_style.color = colorf_black(); m_title_style.font = font_hershey(); m_title_style.font_modeling = font_filled; m_title_style.encoding = encoding_PAW(); m_background_style.back_color = colorf_white(); m_background_style.line_width = 0; //no border m_background_style.color = colorf_black(); //border m_inner_frame_style.color = colorf_black(); m_inner_frame_style.line_pattern = line_solid; m_grid_style.color = colorf_black(); m_grid_style.line_pattern = line_dashed; m_infos_style.font = font_hershey(); m_infos_style.font_modeling = font_filled; m_infos_style.encoding = encoding_PAW(); m_title_box_style.visible = false; m_title_box_style.font = font_hershey(); m_title_box_style.font_modeling = font_filled; m_title_box_style.encoding = encoding_PAW(); {tools_vforit(style,m_bins_style,it) { (*it) = style(); (*it).modeling = modeling_top_lines(); (*it).marker_size = 5; //for bins1D of profile. }} {tools_vforit(style,m_errors_style,it) {(*it) = style();(*it).visible = false;}} {tools_vforit(style,m_func_style,it) (*it) = style();} {tools_vforit(style,m_points_style,it) { (*it) = style(); (*it).modeling = modeling_markers(); //for gopaw. }} {tools_vforit(style,m_left_hatch_style,it) {(*it) = style();(*it).visible = false;}} {tools_vforit(style,m_right_hatch_style,it) {(*it) = style();(*it).visible = false;}} {tools_vforit(style,m_legend_style,it) {(*it) = style();(*it).visible = false;}} } void gopaw_reset_style() { {tools_vforit(style,m_bins_style,it) { (*it) = style(); (*it).modeling = modeling_top_lines(); (*it).marker_size = 5; //for bins1D of profile. }} {tools_vforit(style,m_errors_style,it) {(*it) = style();(*it).visible = false;}} {tools_vforit(style,m_func_style,it) (*it) = style();} {tools_vforit(style,m_points_style,it) { (*it) = style(); (*it).modeling = modeling_markers(); //for gopaw. }} {tools_vforit(style,m_left_hatch_style,it) {(*it) = style();(*it).visible = false;}} {tools_vforit(style,m_right_hatch_style,it) {(*it) = style();(*it).visible = false;}} {tools_vforit(style,m_legend_style,it) {(*it) = style();(*it).visible = false;}} } typedef std::pair style_item_t; typedef std::vector style_t; bool set_from_style(std::ostream& a_out,const style_t& a_style) { tools_vforcit(style_item_t,a_style,it) { const std::string& key = (*it).first; const std::string& sv = (*it).second; //::printf("debug : plotter::set_from_style : key \"%s\" \"%s\"\n",key.c_str(),sv.c_str()); //if(key=="reset") {} if(key=="tag") { // key to find back s. // see also : // xml_style::load_plotter_style() // xml_style::find_plotter_styles() //width,height,depth : could set from style (for exa for lego). } else if(key=="width") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} width = v; } else if(key=="height") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} height = v; } else if(key=="depth") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} depth = v; } else if(key=="left_margin") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} left_margin = v; } else if(key=="right_margin") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} right_margin = v; } else if(key=="bottom_margin") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} bottom_margin = v; } else if(key=="top_margin") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} top_margin = v; } else if(key=="down_margin") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} down_margin = v; } else if(key=="up_margin") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} up_margin = v; } else if(key=="title") { title = sv; } else if(key=="title_up") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} title_up = v; } else if(key=="title_to_axis") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} title_to_axis = v; } else if(key=="title_height") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} title_height = v; } else if(key=="title_automated") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} title_automated = v; } else if(key=="title_hjust") { hjust v; if(!shjust(sv,v)) {style_failed(a_out,key,sv);return false;} title_hjust = v; } else if(key=="x_axis_enforced") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} x_axis_enforced = v; } else if(key=="x_axis_automated") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} x_axis_automated = v; } else if(key=="x_axis_min") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} x_axis_min = v; } else if(key=="x_axis_max") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} x_axis_max = v; } else if(key=="x_axis_is_log") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} x_axis_is_log = v; } else if(key=="y_axis_enforced") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} y_axis_enforced = v; } else if(key=="y_axis_automated") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} y_axis_automated = v; } else if(key=="y_axis_min") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} y_axis_min = v; } else if(key=="y_axis_max") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} y_axis_max = v; } else if(key=="y_axis_is_log") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} y_axis_is_log = v; } else if(key=="z_axis_enforced") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} z_axis_enforced = v; } else if(key=="z_axis_automated") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} z_axis_automated = v; } else if(key=="z_axis_min") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} z_axis_min = v; } else if(key=="z_axis_max") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} z_axis_max = v; } else if(key=="z_axis_is_log") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} z_axis_is_log = v; } else if(key=="value_top_margin") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} value_top_margin = v; } else if(key=="value_bottom_margin") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} value_bottom_margin = v; } else if(key=="value_bins_with_entries") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} value_bins_with_entries = v; } else if(key=="infos_width") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} infos_width = v; } else if(key=="infos_x_margin") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} infos_x_margin = v; } else if(key=="infos_y_margin") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} infos_y_margin = v; } else if(key=="title_box_width") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} title_box_width = v; } else if(key=="title_box_height") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} title_box_height = v; } else if(key=="title_box_x_margin") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} title_box_x_margin = v; } else if(key=="title_box_y_margin") { float v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} title_box_y_margin = v; } else if(key=="infos_what") { infos_what = sv; // } else if(key=="legends_visible") { // bool v; // if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} // legends_visible = v; } else if(key=="legends_automated") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} legends_automated = v; // } else if(key=="legends_attached_to_infos") { // bool v; // if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} // legends_attached_to_infos = v; } else if(key=="legends_origin") { vec2f v; if(!sto(sv,v)) {style_failed(a_out,key,sv);return false;} legends_origin.setValue(v); } else if(key=="legends_size") { vec2f v; if(!sto(sv,v)) {style_failed(a_out,key,sv);return false;} legends_size.setValue(v); } else if(key=="legends_origin_unit") { unit_type v; if(!sto(sv,v)) {style_failed(a_out,key,sv);return false;} legends_origin_unit.setValue(v); } else if(key=="shape_automated") { bool v; if(!to(sv,v)) {style_failed(a_out,key,sv);return false;} shape_automated = v; } else if(key=="shape") { if(sv=="xy") { shape = xy; } else if(sv=="xyz") { shape = xyz; } else { style_failed(a_out,key,sv);return false; } //legends_string //legends_color //legends_string mf_string //legends_color mf_vec } else { a_out << "tools::sg::plotter::set_from_style : unknown key " << key << "." << std::endl; } } return true; } protected: bool s2axis(const std::string& a_s,sg::axis*& a_axis) { if(a_s=="x_axis") {a_axis = &(x_axis());return true;} else if(a_s=="y_axis") {a_axis = &(y_axis());return true;} else if(a_s=="z_axis") {a_axis = &(z_axis());return true;} else if(a_s=="colormap_axis") {a_axis = &(colormap_axis());return true;} else { a_axis = 0; return false; } } public: bool set_from_string(std::ostream& a_out,cmaps_t& a_cmaps,const std::string& a_field,const std::string& a_value) { // see also plotter_style file. std::string::size_type pos = a_field.find('.'); bool status = true; if(pos==std::string::npos) { style_t _style; _style.push_back(style_item_t(a_field,a_value)); if(!set_from_style(a_out,_style)) status = false; } else { std::vector _words; words(a_field,".",false,_words); if(_words.size()==2) { const std::string& word0 = _words[0]; const std::string& word1 = _words[1]; std::string _s = word1+" "+std::string(a_value); sg::axis* _axis = 0; if(word0=="background_style") {if(!background_style().from_string(a_out,a_cmaps,_s)) status = false;} else if(word0=="title_style") {if(!title_style().from_string(a_out,a_cmaps,_s)) status = false;} else if(word0=="infos_style") {if(!infos_style().from_string(a_out,a_cmaps,_s)) status = false;} else if(word0=="title_box_style") {if(!title_box_style().from_string(a_out,a_cmaps,_s)) status = false;} else if(word0=="inner_frame_style") {if(!inner_frame_style().from_string(a_out,a_cmaps,_s)) status = false;} else if(word0=="grid_style") {if(!grid_style().from_string(a_out,a_cmaps,_s)) status = false;} else if(word0=="wall_style") {if(!wall_style().from_string(a_out,a_cmaps,_s)) status = false;} else if(!s2axis(word0,_axis)) { a_out << "tools::sg::plotter::set_from_string : unexpected axis field " << word0 << "." << std::endl; status = false; } else { style_t _style; _style.push_back(style_item_t(word1,a_value)); if(!_axis->set_from_style(a_out,_style)) status = false; } } else if(_words.size()==3) { const std::string& word0 = _words[0]; const std::string& word1 = _words[1]; const std::string& word2 = _words[2]; sg::axis* _axis = 0; std::string _s = word2+" "+std::string(a_value); unsigned int index; bool to_status = to(word1,index); if(word0=="bins_style") { if(!to_status) { a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl; status = false; } else { if(!bins_style(index).from_string(a_out,a_cmaps,_s)) status = false; } } else if(word0=="errors_style") { if(!to_status) { a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl; status = false; } else { if(!errors_style(index).from_string(a_out,a_cmaps,_s)) status = false; } } else if(word0=="func_style") { if(!to_status) { a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl; status = false; } else { if(!func_style(index).from_string(a_out,a_cmaps,_s)) status = false; } } else if(word0=="points_style") { if(!to_status) { a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl; status = false; } else { if(!points_style(index).from_string(a_out,a_cmaps,_s)) status = false; } } else if(word0=="left_hatch_style") { if(!to_status) { a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl; status = false; } else { if(!left_hatch_style(index).from_string(a_out,a_cmaps,_s)) status = false; } } else if(word0=="right_hatch_style") { if(!to_status) { a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl; status = false; } else { if(!right_hatch_style(index).from_string(a_out,a_cmaps,_s)) status = false; } } else if(word0=="legend_style") { if(!to_status) { a_out << "tools::sg::plotter::set_from_string : bad string " << word1 << " for an index." << std::endl; status = false; } else { if(!legend_style(index).from_string(a_out,a_cmaps,_s)) status = false; } } else if(!s2axis(word0,_axis)) { a_out << "tools::sg::plotter::set_from_string : unexpected axis field " << word0 << "." << std::endl; status = false; } else { if(word1=="line_style") {if(!_axis->line_style().from_string(a_out,a_cmaps,_s)) status = false;} else if(word1=="ticks_style") {if(!_axis->ticks_style().from_string(a_out,a_cmaps,_s)) status = false;} else if(word1=="labels_style") {if(!_axis->labels_style().from_string(a_out,a_cmaps,_s)) status = false;} else if(word1=="mag_style") {if(!_axis->mag_style().from_string(a_out,a_cmaps,_s)) status = false;} else if(word1=="title_style") {if(!_axis->title_style().from_string(a_out,a_cmaps,_s)) status = false;} else { a_out << "tools::sg::plotter::set_from_string : unexpected style field " << word1 << "." << std::endl; status = false; } } } else { a_out << "tools::sg::plotter::set_from_string : unexpected number of fields " << _words.size() << "." << std::endl; status = false; } } return status; } void set_encoding(const std::string& a_value) { title_style().encoding = a_value; infos_style().encoding = a_value; title_box_style().encoding = a_value; m_x_axis.set_encoding(a_value); m_y_axis.set_encoding(a_value); m_z_axis.set_encoding(a_value); m_cmap_axis.set_encoding(a_value); } void set_encoding_none() {set_encoding(encoding_none());} void print_available_customization(std::ostream& a_out) const { a_out << "plotter fields :" << std::endl; {const std::vector& fds = node_desc_fields(); tools_vforcit(field_desc,fds,itd) { a_out << " " << (*itd).name() << ", class " << (*itd).cls() << std::endl; }} a_out << std::endl; a_out << "plotter data available styles :" << std::endl; a_out << " bins_style., class style" << std::endl; a_out << " errors_style., class style" << std::endl; a_out << " func_style., class style" << std::endl; a_out << " points_style., class style" << std::endl; a_out << " left_hatch_style., class style" << std::endl; a_out << " right_hatch_style., class style" << std::endl; a_out << " legend_style., class style" << std::endl; a_out << std::endl; a_out << "plotter available styles :" << std::endl; a_out << " title_style, class text_style" << std::endl; a_out << " infos_style, class text_style" << std::endl; a_out << " title_box_style, class text_style" << std::endl; a_out << " background_style, class style" << std::endl; a_out << " inner_frame_style, class style" << std::endl; a_out << " grid_style, class style" << std::endl; a_out << " wall_style, class style" << std::endl; a_out << std::endl; a_out << "plotter available axes :" << std::endl; a_out << " x_axis" << std::endl; a_out << " y_axis" << std::endl; a_out << " z_axis" << std::endl; a_out << " colormap_axis" << std::endl; a_out << std::endl; a_out << "plotter axis available styles :" << std::endl; a_out << " title_style, class text_style" << std::endl; a_out << " labels_style, class text_style" << std::endl; a_out << " mag_style, class text_style" << std::endl; a_out << " line_style, class line_style" << std::endl; a_out << " ticks_style, class line_style" << std::endl; a_out << std::endl; a_out << "plotter style class fields :" << std::endl; {style _style; const std::vector& fds = _style.node_desc_fields(); tools_vforcit(field_desc,fds,itd) { a_out << " " << (*itd).name() << ", class " << (*itd).cls() << std::endl; }} a_out << std::endl; a_out << "plotter text_style class fields :" << std::endl; {text_style _style; const std::vector& fds = _style.node_desc_fields(); tools_vforcit(field_desc,fds,itd) { a_out << " " << (*itd).name() << ", class " << (*itd).cls() << std::endl; }} a_out << std::endl; a_out << "plotter line_style class fields :" << std::endl; {line_style _style; const std::vector& fds = _style.node_desc_fields(); tools_vforcit(field_desc,fds,itd) { a_out << " " << (*itd).name() << ", class " << (*itd).cls() << std::endl; }} a_out << std::endl; } protected: void style_failed(std::ostream& a_out,const std::string& a_key,const std::string& a_value) { a_out << "tools::sg::plotter::set_from_style :" << " failed for key " << sout(a_key) << " and value " << sout(a_value) << "." << std::endl; } public: virtual void render(render_action& a_action) { if(touched()) { update_sg(a_action.out()); reset_touched(); } m_group.render(a_action); } virtual void pick(pick_action& a_action) { if(touched()) { update_sg(a_action.out()); reset_touched(); } nodekit_pick(a_action,m_group,this); } virtual void search(search_action& a_action) { if(touched()) { update_sg(a_action.out()); reset_touched(); } node::search(a_action); if(a_action.done()) return; m_group.search(a_action); } virtual void bbox(bbox_action& a_action) { if(touched()) { update_sg(a_action.out()); reset_touched(); } m_group.bbox(a_action); } virtual bool write(write_action& a_action) { if(touched()) { update_sg(a_action.out()); reset_touched(); } //if(!write_fields(a_action)) return false; return m_group.write(a_action); } public: plotter(const base_freetype& a_ttf) :parent() ,width(0) ,height(0) ,left_margin(0) ,right_margin(0) ,bottom_margin(0) ,top_margin(0) ,depth(0) ,down_margin(0) ,up_margin(0) ,title_up(true) ,title_to_axis(0) //set below. ,title_height(0) //set below. ,title_automated(true) ,title_hjust(center) ,title("") ,colormap_visible(true) ,colormap_axis_labeling(cells) ,colormap_attached(true) ,colormap_axis_visible(true) ,x_axis_enforced(false) ,x_axis_automated(true) ,x_axis_min(0) ,x_axis_max(1) ,x_axis_is_log(false) ,y_axis_enforced(false) ,y_axis_automated(true) ,y_axis_min(0) ,y_axis_max(1) ,y_axis_is_log(false) ,z_axis_enforced(false) ,z_axis_automated(true) ,z_axis_min(0) ,z_axis_max(1) ,z_axis_is_log(false) ,value_top_margin(0.1f) //percent. // CERN-PAW seems to have 0.1F and CERN-ROOT 0.05F. ,value_bottom_margin(0.0f) //percent. ,value_bins_with_entries(true) ,infos_width(0.3f) //percent of width ,infos_x_margin(default_infos_margin()) //percent of width ,infos_y_margin(default_infos_margin()) //percent of height ,infos_what(s_infos_what_def()) ,title_box_width(default_title_box_width()) //percent of width ,title_box_height(default_title_box_height()) //percent of height ,title_box_x_margin(default_title_box_x_margin()) //percent of width ,title_box_y_margin(default_title_box_y_margin()) //percent of height ,func2D_borders_visible(true) ,theta(30) ,phi(30) ,tau(-90) ,legends_automated(true) //,legends_attached_to_infos(true) // if legends_attached_to_infos is false and // unit_percent, legends_origin is the position // of the upper right corner of the legends // relative to the upper right corner of the plotter // with positive values going in reverse x,y axis. //,legends_origin(vec2f(0.01f,0.01f)) //,legends_origin_unit(unit_percent) //,legends_size(vec2f(0.2f,0.16f)) //legends_string ,shape_automated(true) ,shape(xy) ,xy_depth(0.01f) ,curve_number_of_points(100) ,data_light_on_automated(true) ,primitives_enforced(false) ,inner_frame_enforced(false) ,number_of_levels(10) ,levels() ,m_ttf(a_ttf) ,m_cmap_axis(a_ttf) ,m_x_axis(a_ttf) ,m_y_axis(a_ttf) ,m_z_axis(a_ttf) ,m_shape(xy) { m_cmaps[style_default_colormap::s_default()] = style_default_colormap(); //costly add_fields(); reset_style(true); init_sg(); // skeleton of scene graph. } virtual ~plotter(){ clear_plottables(); clear_primitives(); clear_cmaps(); } public: plotter(const plotter& a_from) :parent(a_from) ,width(a_from.width) ,height(a_from.height) ,left_margin(a_from.left_margin) ,right_margin(a_from.right_margin) ,bottom_margin(a_from.bottom_margin) ,top_margin(a_from.top_margin) ,depth(a_from.depth) ,down_margin(a_from.down_margin) ,up_margin(a_from.up_margin) ,title_up(a_from.title_up) ,title_to_axis(a_from.title_to_axis) ,title_height(a_from.title_height) ,title_automated(a_from.title_automated) ,title_hjust(a_from.title_hjust) ,title(a_from.title) ,colormap_visible(a_from.colormap_visible) ,colormap_axis_labeling(a_from.colormap_axis_labeling) ,colormap_attached(a_from.colormap_attached) ,colormap_axis_visible(a_from.colormap_axis_visible) ,x_axis_enforced(a_from.x_axis_enforced) ,x_axis_automated(a_from.x_axis_automated) ,x_axis_min(a_from.x_axis_min) ,x_axis_max(a_from.x_axis_max) ,x_axis_is_log(a_from.x_axis_is_log) ,y_axis_enforced(a_from.y_axis_enforced) ,y_axis_automated(a_from.y_axis_automated) ,y_axis_min(a_from.y_axis_min) ,y_axis_max(a_from.y_axis_max) ,y_axis_is_log(a_from.y_axis_is_log) ,z_axis_enforced(a_from.z_axis_enforced) ,z_axis_automated(a_from.z_axis_automated) ,z_axis_min(a_from.z_axis_min) ,z_axis_max(a_from.z_axis_max) ,z_axis_is_log(a_from.z_axis_is_log) ,value_top_margin(a_from.value_top_margin) ,value_bottom_margin(a_from.value_bottom_margin) ,value_bins_with_entries(a_from.value_bins_with_entries) ,infos_width(a_from.infos_width) ,infos_x_margin(a_from.infos_x_margin) ,infos_y_margin(a_from.infos_y_margin) ,infos_what(a_from.infos_what) ,title_box_width(a_from.title_box_width) ,title_box_height(a_from.title_box_height) ,title_box_x_margin(a_from.title_box_x_margin) ,title_box_y_margin(a_from.title_box_y_margin) ,func2D_borders_visible(a_from.func2D_borders_visible) ,theta(a_from.theta) ,phi(a_from.phi) ,tau(a_from.tau) ,legends_automated(a_from.legends_automated) //,legends_attached_to_infos(a_from.legends_attached_to_infos) ,legends_origin(a_from.legends_origin) ,legends_origin_unit(a_from.legends_origin_unit) ,legends_size(a_from.legends_size) ,legends_string(a_from.legends_string) ,shape_automated(a_from.shape_automated) ,shape(a_from.shape) ,xy_depth(a_from.xy_depth) ,curve_number_of_points(a_from.curve_number_of_points) ,data_light_on_automated(a_from.data_light_on_automated) ,primitives_enforced(a_from.primitives_enforced) ,inner_frame_enforced(a_from.inner_frame_enforced) ,number_of_levels(a_from.number_of_levels) ,levels(a_from.levels) ,m_ttf(a_from.m_ttf) ,m_background_sep() ,m_cmap_axis(m_ttf) ,m_x_axis(m_ttf) ,m_y_axis(m_ttf) ,m_z_axis(m_ttf) ,m_etc_sep(a_from.m_etc_sep) ,m_shape(a_from.m_shape) ,m_bins_style(a_from.m_bins_style) ,m_errors_style(a_from.m_errors_style) ,m_func_style(a_from.m_func_style) ,m_points_style(a_from.m_points_style) ,m_left_hatch_style(a_from.m_left_hatch_style) ,m_right_hatch_style(a_from.m_right_hatch_style) ,m_legend_style(a_from.m_legend_style) ,m_title_style(a_from.m_title_style) ,m_infos_style(a_from.m_infos_style) ,m_title_box_style(a_from.m_title_box_style) ,m_background_style(a_from.m_background_style) ,m_wall_style(a_from.m_wall_style) ,m_inner_frame_style(a_from.m_inner_frame_style) ,m_grid_style(a_from.m_grid_style) ,m_cmaps(a_from.m_cmaps) { add_fields(); // to copy axes styles : m_x_axis = a_from.m_x_axis; m_y_axis = a_from.m_y_axis; m_z_axis = a_from.m_z_axis; m_cmap_axis = a_from.m_cmap_axis; init_sg(); // skeleton of scene graph. {tools_vforcit(plottable*,a_from.m_plottables,it) {m_plottables.push_back((*it)->copy());}} {tools_vforcit(plotprim*,a_from.m_primitives,it) {m_primitives.push_back((*it)->copy());}} } plotter& operator=(const plotter& a_from){ parent::operator=(a_from); if(&a_from==this) return *this; width = a_from.width; height = a_from.height; left_margin = a_from.left_margin; right_margin = a_from.right_margin; bottom_margin = a_from.bottom_margin; top_margin = a_from.top_margin; depth = a_from.depth; down_margin = a_from.down_margin; up_margin = a_from.up_margin; title_up = a_from.title_up; title_to_axis = a_from.title_to_axis; title_height = a_from.title_height; title_automated = a_from.title_automated; title_hjust = a_from.title_hjust; title = a_from.title; colormap_visible = a_from.colormap_visible; colormap_axis_labeling = a_from.colormap_axis_labeling; colormap_attached = a_from.colormap_attached; colormap_axis_visible = a_from.colormap_axis_visible; x_axis_enforced = a_from.x_axis_enforced; x_axis_automated = a_from.x_axis_automated; x_axis_min = a_from.x_axis_min; x_axis_max = a_from.x_axis_max; x_axis_is_log = a_from.x_axis_is_log; y_axis_enforced = a_from.y_axis_enforced; y_axis_automated = a_from.y_axis_automated; y_axis_min = a_from.y_axis_min; y_axis_max = a_from.y_axis_max; y_axis_is_log = a_from.y_axis_is_log; z_axis_enforced = a_from.z_axis_enforced; z_axis_automated = a_from.z_axis_automated; z_axis_min = a_from.z_axis_min; z_axis_max = a_from.z_axis_max; z_axis_is_log = a_from.z_axis_is_log; value_top_margin = a_from.value_top_margin; value_bottom_margin = a_from.value_bottom_margin; value_bins_with_entries = a_from.value_bins_with_entries; infos_width = a_from.infos_width; infos_x_margin = a_from.infos_x_margin; infos_y_margin = a_from.infos_y_margin; infos_what = a_from.infos_what; title_box_width = a_from.title_box_width; title_box_height = a_from.title_box_height; title_box_x_margin = a_from.title_box_x_margin; title_box_y_margin = a_from.title_box_y_margin; func2D_borders_visible = a_from.func2D_borders_visible; theta = a_from.theta; phi = a_from.phi; tau = a_from.tau; legends_automated = a_from.legends_automated; //legends_attached_to_infos = a_from.legends_attached_to_infos; legends_origin = a_from.legends_origin; legends_origin_unit = a_from.legends_origin_unit; legends_size = a_from.legends_size; legends_string = a_from.legends_string; shape_automated = a_from.shape_automated; shape = a_from.shape; xy_depth = a_from.xy_depth; curve_number_of_points = a_from.curve_number_of_points; number_of_levels = a_from.number_of_levels; levels = a_from.levels; data_light_on_automated = a_from.data_light_on_automated; primitives_enforced = a_from.primitives_enforced; inner_frame_enforced = a_from.inner_frame_enforced; m_etc_sep = a_from.m_etc_sep; m_bins_style = a_from.m_bins_style; m_errors_style = a_from.m_errors_style; m_func_style = a_from.m_func_style; m_points_style = a_from.m_points_style; m_left_hatch_style = a_from.m_left_hatch_style; m_right_hatch_style = a_from.m_right_hatch_style; m_legend_style = a_from.m_legend_style; m_title_style = a_from.m_title_style; m_infos_style = a_from.m_infos_style; m_title_box_style = a_from.m_title_box_style; m_background_style = a_from.m_background_style; m_wall_style = a_from.m_wall_style; m_inner_frame_style = a_from.m_inner_frame_style; m_grid_style = a_from.m_grid_style; // to copy axes styles : m_x_axis = a_from.m_x_axis; m_y_axis = a_from.m_y_axis; m_z_axis = a_from.m_z_axis; m_cmap_axis = a_from.m_cmap_axis; m_cmaps = a_from.m_cmaps; clear_plottables(); clear_primitives(); clear_todels(); {tools_vforcit(plottable*,a_from.m_plottables,it) {m_plottables.push_back((*it)->copy());}} {tools_vforcit(plotprim*,a_from.m_primitives,it) {m_primitives.push_back((*it)->copy());}} return *this; } public: size_t number_of_plottables() const { size_t number = 0; tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(!object->is_valid()) continue; // take into account all valid plottables, even the one without a representation. number++; } return number; } #define TOOLS_SG_PLOTTER_NUMBER_OF(a__what) \ size_t number_of_plotted_##a__what##s() const {\ size_t number = 0;\ tools_vforcit(plottable*,m_plottables,it) {\ plottable* object = *it;\ if(!object) continue;\ if(!object->is_valid()) continue;\ if(safe_cast(*object)) number++;\ }\ return number;\ } TOOLS_SG_PLOTTER_NUMBER_OF(bins1D) TOOLS_SG_PLOTTER_NUMBER_OF(bins2D) TOOLS_SG_PLOTTER_NUMBER_OF(points2D) TOOLS_SG_PLOTTER_NUMBER_OF(points3D) TOOLS_SG_PLOTTER_NUMBER_OF(func1D) TOOLS_SG_PLOTTER_NUMBER_OF(func2D) #undef TOOLS_SG_PLOTTER_NUMBER_OF void plotted_object_names(std::vector& a_names) const { a_names.clear(); tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(!object->is_valid()) continue; // take into account all valid plottables, even the one without a representation. a_names.push_back(object->name()); } } public: //public const torche& data_light() const {return m_data_light;} torche& data_light() {return m_data_light;} matrix& tsf() {return m_tsf;} const separator& etc_sep() const {return m_etc_sep;} separator& etc_sep() {return m_etc_sep;} const std::vector& plottables() const {return m_plottables;} void add_plottable(plottable* a_p) { //WARNING : it takes ownership of a_p object. m_plottables.push_back(a_p); touch(); } void prep_plottable(plottable* a_p) { //WARNING : it takes ownership of a_p object. m_plottables.insert(m_plottables.begin(),a_p); touch(); } void transfer_plottables(std::vector& a_to) { a_to = m_plottables; m_plottables.clear(); //do not delete plottables ! touch(); } template bool remove_plottables() { bool found = false; std::vector::iterator it; for(it=m_plottables.begin();it!=m_plottables.end();) { plottable* object = *it; if(object && safe_cast(*object)) { it = m_plottables.erase(it); delete object; found = true; } else { it++; } } if(found) touch(); return found; } void add_primitive(plotprim* a_prim) {m_primitives.push_back(a_prim);touch();} void transfer_primitives(std::vector& a_to) { a_to = m_primitives; m_primitives.clear(); //do not delete primitives ! touch(); } template void add_todel(T* a_obj) { m_todel_group.add(new sg::holder(a_obj)); } template void remove_todels(){ remove_holders(m_todel_group.children()); } void transfer_todels(std::vector& a_to) { //used in sg::plots. m_todel_group.transfer(a_to); } void add_node_todel(node* a_node) { //used in sg::plots. m_todel_group.add(a_node); } void clear() { clear_plottables(); clear_primitives(); clear_todels(); legends_string.clear(); legends_origin_unit.clear(); legends_origin.clear(); legends_size.clear(); //wallEnforced.setValue(false); //gridEnforced.setValue(false); primitives_enforced = false; inner_frame_enforced = false; //getEtcSeparator()->removeAllChildren(); //getEtcDataSeparator()->removeAllChildren(); } const sg::axis& x_axis() const {return m_x_axis;} sg::axis& x_axis() {return m_x_axis;} const sg::axis& y_axis() const {return m_y_axis;} sg::axis& y_axis() {return m_y_axis;} const sg::axis& z_axis() const {return m_z_axis;} sg::axis& z_axis() {return m_z_axis;} const sg::axis& colormap_axis() const {return m_cmap_axis;} sg::axis& colormap_axis() {return m_cmap_axis;} text_style& title_style() {return m_title_style;} style& background_style() {return m_background_style;} style& wall_style() {return m_wall_style;} style& inner_frame_style() {return m_inner_frame_style;} style& grid_style() {return m_grid_style;} text_style& infos_style() {return m_infos_style;} text_style& title_box_style() {return m_title_box_style;} style& bins_style(size_t a_index) { size_t sz = m_bins_style.size(); if(a_index>=sz) { //012345 sz=6 // 9 a_index wanted // 6789 loop for(size_t index=sz;index<=a_index;index++) { m_bins_style.push_back(style()); m_bins_style.back().modeling = modeling_top_lines(); m_bins_style.back().marker_size = 5; //for bins1D of profile. } } return m_bins_style[a_index]; } style& errors_style(size_t a_index) { size_t sz = m_errors_style.size(); if(a_index>=sz) { for(size_t index=sz;index<=a_index;index++) { m_errors_style.push_back(style()); m_errors_style.back().visible = false; } } return m_errors_style[a_index]; } style& func_style(size_t a_index) { size_t sz = m_func_style.size(); if(a_index>=sz) { for(size_t index=sz;index<=a_index;index++) { m_func_style.push_back(style()); } } return m_func_style[a_index]; } style& points_style(size_t a_index) { size_t sz = m_points_style.size(); if(a_index>=sz) { //012345 sz=6 // 9 a_index wanted // 6789 loop for(size_t index=sz;index<=a_index;index++) { m_points_style.push_back(style()); m_points_style.back().modeling = modeling_markers(); //for gopaw. } } return m_points_style[a_index]; } style& left_hatch_style(size_t a_index) { size_t sz = m_left_hatch_style.size(); if(a_index>=sz) { for(size_t index=sz;index<=a_index;index++) { m_left_hatch_style.push_back(style()); m_left_hatch_style.back().visible = false; } } return m_left_hatch_style[a_index]; } style& right_hatch_style(size_t a_index) { size_t sz = m_right_hatch_style.size(); if(a_index>=sz) { for(size_t index=sz;index<=a_index;index++) { m_right_hatch_style.push_back(style()); m_right_hatch_style.back().visible = false; } } return m_right_hatch_style[a_index]; } style& legend_style(size_t a_index) { size_t sz = m_legend_style.size(); if(a_index>=sz) { for(size_t index=sz;index<=a_index;index++) { m_legend_style.push_back(style()); } } return m_legend_style[a_index]; } void bins_modelings(size_t a_index,std::vector& a_opts) { a_opts.clear(); update_shape(); if(m_shape==xy) { size_t ibins = 0; tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(bins1D* b1 = safe_cast(*object)) { //update_bins1D_xy if(a_index==ibins) { if(b1->is_profile()) { a_opts.push_back(modeling_points()); a_opts.push_back(modeling_markers()); return; } else { a_opts.push_back(modeling_boxes()); a_opts.push_back(modeling_wire_boxes()); a_opts.push_back(modeling_bar_chart()); a_opts.push_back(modeling_top_lines()); a_opts.push_back(modeling_points()); a_opts.push_back(modeling_markers()); return; } } ibins++; } if(safe_cast(*object)) { //update_bins2D_xy if(a_index==ibins) { a_opts.push_back(modeling_curve()); a_opts.push_back(modeling_filled_curve()); a_opts.push_back(modeling_boxes()); a_opts.push_back(modeling_wire_boxes()); a_opts.push_back(modeling_solid()); a_opts.push_back(modeling_points()); return; } ibins++; } } } } bool xx_2_yy(const vec3f& a_pos,vec3f& a_out) const { // a_pos is in data frame NDC coordinates. {float XSIZ = width; float XMGL = left_margin; float XMGR = right_margin; float wData = XSIZ-XMGL-XMGR; a_out[0] = wData*a_pos[0];} {float YSIZ = height; float YMGL = bottom_margin; float YMGU = top_margin; float hData = YSIZ-YMGL-YMGU; a_out[1] = hData*a_pos[1];} {float ZSIZ = depth; float ZMGD = down_margin; float ZMGU = up_margin; float dData = ZSIZ-ZMGD-ZMGU; a_out[2] = dData*a_pos[2];} return true; } bool data_frame_2_vp(const vec3f& a_pos,vec3f& a_vp) const { // a_pos is in data frame NDC coordinates. // a_vp is in viewport/screen coordinates (in [0,1]). {float XSIZ = width; float XMGL = left_margin; float XMGR = right_margin; float wData = XSIZ-XMGL-XMGR; if(XSIZ==0.0F) { //SoDebugError::postInfo("tools::sg;:plotter::data_frame_2_vp","XSIZ is 0"); return false; } a_vp[0] = (wData*a_pos[0] + XMGL)/XSIZ;} {float YSIZ = height; float YMGL = bottom_margin; float YMGU = top_margin; float hData = YSIZ-YMGL-YMGU; if(YSIZ==0.0F) { //SoDebugError::postInfo("tools::sg;:plotter::data_frame_2_vp","YSIZ is 0"); return false; } a_vp[1] = (hData*a_pos[1] + YMGL)/YSIZ;} {float ZSIZ = depth; float ZMGD = down_margin; float ZMGU = up_margin; float dData = ZSIZ-ZMGD-ZMGU; if(ZSIZ==0.0F) { //SoDebugError::postInfo("tools::sg;:plotter::data_frame_2_vp","ZSIZ is 0"); return false; } a_vp[2] = (dData*a_pos[2] + ZMGD)/ZSIZ;} return true; } bool vp_2_data_frame(const vec3f& a_vp,vec3f& a_pos) const { // a_vp is in viewport/screen coordinates (in [0,1]). // a_pos is in data frame NDC coordinates. {float XSIZ = width; float XMGL = left_margin; float XMGR = right_margin; float wData = XSIZ-XMGL-XMGR; if(wData==0.0F) { //SoDebugError::postInfo("tools::sg;:plotter::vp_2_data_frame","wData is 0"); return false; } a_pos[0] = (a_vp[0]*XSIZ - XMGL)/wData;} {float YSIZ = height; float YMGL = bottom_margin; float YMGU = top_margin; float hData = YSIZ-YMGL-YMGU; if(hData==0.0F) { //SoDebugError::postInfo("tools::sg;:plotter::vp_2_data_frame","hData is 0"); return false; } a_pos[1] = (a_vp[1]*YSIZ - YMGL)/hData;} {float ZSIZ = depth; float ZMGD = down_margin; float ZMGU = up_margin; float dData = ZSIZ-ZMGD-ZMGU; if(dData==0.0F) { //SoDebugError::postInfo("tools::sg;:plotter::vp_2_data_frame","dData is 0"); return false; } a_pos[2] = (a_vp[2]*ZSIZ - ZMGD)/dData;} return true; } bool data_frame_2_axis(const vec3f& aDF,vec3f& a_pos) const { // aDF is in data area coordinates. In [0,1][0,1][0,1]. // a_pos is in axes coordinates. // Assume that axes min,max,is_log are up to date. {float mn = m_x_axis.minimum_value; float mx = m_x_axis.maximum_value; bool lg = m_x_axis.is_log; if(lg) { mn = fpow(10,mn); mx = fpow(10,mx); } a_pos[0] = verify_log_inv(aDF[0],mn,mx-mn,lg);} {float mn = m_y_axis.minimum_value; float mx = m_y_axis.maximum_value; bool lg = m_y_axis.is_log; if(lg) { mn = fpow(10,mn); mx = fpow(10,mx); } a_pos[1] = verify_log_inv(aDF[1],mn,mx-mn,lg);} {float mn = m_z_axis.minimum_value; float mx = m_z_axis.maximum_value; bool lg = m_z_axis.is_log; if(lg) { mn = fpow(10,mn); mx = fpow(10,mx); } a_pos[2] = verify_log_inv(aDF[2],mn,mx-mn,lg);} return true; } bool axis_2_data_frame(const vec3f& a_pos,vec3f& aDF) const { // a_pos is in axes coordinates. // aDF in data area coordinate. In [0,1][0,1][0,1]. // Assume that axes min,max,logScale are up to date. {float mn = m_x_axis.minimum_value; float mx = m_x_axis.maximum_value; if(mx==mn) { //SoDebugError::postInfo // ("tools::sg;:plotter::axis_2_data_frame","x : mn (%g) == mx (%g)",mn,mx); return false; } bool lg = m_x_axis.is_log; if(lg) { if(mn<=0) { //SoDebugError::postInfo // ("tools::sg;:plotter::axis_2_data_frame","x log but mn (%g) <=0",mn); return false; } if(mx<=0) { //SoDebugError::postInfo // ("tools::sg;:plotter::axis_2_data_frame","x log but mx (%g) <=0",mx); return false; } mn = flog10(mn); mx = flog10(mx); } aDF[0] = verify_log(a_pos[0],mn,mx-mn,lg);} {float mn = m_y_axis.minimum_value; float mx = m_y_axis.maximum_value; if(mx==mn) { //SoDebugError::postInfo // ("tools::sg;:plotter::axis_2_data_frame","y : mn (%g) == mx (%g)",mn,mx); return false; } bool lg = m_y_axis.is_log; if(lg) { if(mn<=0) { //SoDebugError::postInfo // ("tools::sg;:plotter::axis_2_data_frame","y log but mn (%g) <=0",mn); return false; } if(mx<=0) { //SoDebugError::postInfo // ("tools::sg;:plotter::axis_2_data_frame","y log but mx (%g) <=0",mx); return false; } mn = flog10(mn); mx = flog10(mx); } aDF[1] = verify_log(a_pos[1],mn,mx-mn,lg);} {float mn = m_z_axis.minimum_value; float mx = m_z_axis.maximum_value; if(mx==mn) { //SoDebugError::postInfo // ("tools::sg;:plotter::axis_2_data_frame","z : mn (%g) == mx (%g)",mn,mx); return false; } bool lg = m_z_axis.is_log; if(lg) { if(mn<=0) { //SoDebugError::postInfo // ("tools::sg;:plotter::axis_2_data_frame","z log but mn (%g) <=0",mn); return false; } if(mx<=0) { //SoDebugError::postInfo // ("tools::sg;:plotter::axis_2_data_frame","z log but mx (%g) <=0",mx); return false; } mn = flog10(mn); mx = flog10(mx); } aDF[2] = verify_log(a_pos[2],mn,mx-mn,lg);} return true; } bool axis_2_vp(const vec3f& a_pos,vec3f& a_vp) const { // a_pos is in axes coordinates. // a_vp is in viewport/screen coordinates (in [0,1]). vec3f d; // In data area coordinate. In [0,1][0,1][0,1]. if(!axis_2_data_frame(a_pos,d)) return false; return data_frame_2_vp(d,a_vp); } bool vp_2_axis(const vec3f& a_vp,vec3f& a_pos) const { // a_vp is in viewport/screen coordinates (in [0,1]). // a_pos is in axes coordinates. vec3f d; // In data area coordinate. In [0,1][0,1][0,1]. if(!vp_2_data_frame(a_vp,d)) return false; return data_frame_2_axis(d,a_pos); } public: void set_axes_modeling(const std::string& a_v){ m_x_axis.modeling = a_v; m_y_axis.modeling = a_v; m_z_axis.modeling = a_v; m_cmap_axis.modeling = a_v; } void set_axes_color(const colorf& a_color){ m_x_axis.line_style().color = a_color; m_x_axis.ticks_style().color = a_color; m_x_axis.labels_style().color = a_color; m_x_axis.title_style().color = a_color; m_x_axis.mag_style().color = a_color; m_y_axis.line_style().color = a_color; m_y_axis.ticks_style().color = a_color; m_y_axis.labels_style().color = a_color; m_y_axis.title_style().color = a_color; m_y_axis.mag_style().color = a_color; m_z_axis.line_style().color = a_color; m_z_axis.ticks_style().color = a_color; m_z_axis.labels_style().color = a_color; m_z_axis.title_style().color = a_color; m_z_axis.mag_style().color = a_color; m_cmap_axis.line_style().color = a_color; m_cmap_axis.ticks_style().color = a_color; m_cmap_axis.labels_style().color = a_color; m_cmap_axis.title_style().color = a_color; m_cmap_axis.mag_style().color = a_color; } void set_axes_text_scale(float a_v){ m_x_axis.labels_style().scale = a_v; m_x_axis.title_style().scale = a_v; m_x_axis.mag_style().scale = a_v; m_y_axis.labels_style().scale = a_v; m_y_axis.title_style().scale = a_v; m_y_axis.mag_style().scale = a_v; m_z_axis.labels_style().scale = a_v; m_z_axis.title_style().scale = a_v; m_z_axis.mag_style().scale = a_v; m_cmap_axis.labels_style().scale = a_v; m_cmap_axis.title_style().scale = a_v; m_cmap_axis.mag_style().scale = a_v; } void set_axes_line_pattern(unsigned short a_v){ m_x_axis.line_style().pattern = a_v; m_y_axis.line_style().pattern = a_v; m_z_axis.line_style().pattern = a_v; m_cmap_axis.line_style().pattern = a_v; } void set_axes_line_width(int a_v){ m_x_axis.line_style().width = float(a_v); m_y_axis.line_style().width = float(a_v); m_z_axis.line_style().width = float(a_v); m_cmap_axis.line_style().width = float(a_v); m_x_axis.ticks_style().width = float(a_v); m_y_axis.ticks_style().width = float(a_v); m_z_axis.ticks_style().width = float(a_v); m_cmap_axis.ticks_style().width = float(a_v); } void set_axes_tick_length(float a_v){ m_x_axis.tick_length = a_v; m_y_axis.tick_length = a_v; m_z_axis.tick_length = a_v; m_cmap_axis.tick_length = a_v; } void set_axes_title_height(float a_v){ m_x_axis.title_height = a_v; m_y_axis.title_height = a_v; m_z_axis.title_height = a_v; m_cmap_axis.title_height = a_v; } void set_axes_label_height(float a_v){ m_x_axis.label_height = a_v; m_y_axis.label_height = a_v; m_z_axis.label_height = a_v; m_cmap_axis.label_height = a_v; } void set_axes_font_modeling(font_modeling a_v){ m_x_axis.labels_style().font_modeling = a_v; m_x_axis.title_style().font_modeling = a_v; m_x_axis.mag_style().font_modeling = a_v; m_y_axis.labels_style().font_modeling = a_v; m_y_axis.title_style().font_modeling = a_v; m_y_axis.mag_style().font_modeling = a_v; m_z_axis.labels_style().font_modeling = a_v; m_z_axis.title_style().font_modeling = a_v; m_z_axis.mag_style().font_modeling = a_v; m_cmap_axis.labels_style().font_modeling = a_v; m_cmap_axis.title_style().font_modeling = a_v; m_cmap_axis.mag_style().font_modeling = a_v; } void set_font_modeling(font_modeling a_v){ set_axes_font_modeling(a_v); title_style().font_modeling = a_v; infos_style().font_modeling = a_v; title_box_style().font_modeling = a_v; } protected: void init_sg(){ m_group.add(new noderef(m_background_sep)); m_group.add(new noderef(m_cmap_sep)); m_group.add(new noderef(m_infos_title_sep)); m_group.add(new noderef(m_infos_sep)); m_group.add(new noderef(m_legend_sep)); m_group.add(new noderef(m_title_box_sep)); m_group.add(new noderef(m_tsf)); m_group.add(new noderef(m_layout)); m_group.add(new noderef(m_title_sep)); m_group.add(new noderef(m_x_axis_sep)); m_group.add(new noderef(m_y_axis_sep)); m_group.add(new noderef(m_z_axis_sep)); m_group.add(new noderef(m_grid_sep)); m_group.add(new noderef(m_data_sep)); m_group.add(new noderef(m_primitives_sep)); m_cmap_sep.add(new noderef(m_cmap_matrix)); m_cmap_sep.add(new noderef(m_cmap_cells_sep)); m_cmap_sep.add(new noderef(m_cmap_axis_matrix)); m_cmap_sep.add(new noderef(m_cmap_axis)); m_x_axis_sep.add(new noderef(m_x_axis_matrix)); m_x_axis_sep.add(new noderef(m_x_axis)); m_y_axis_sep.add(new noderef(m_y_axis_matrix)); m_y_axis_sep.add(new noderef(m_y_axis)); m_z_axis_sep.add(new noderef(m_z_axis_matrix)); m_z_axis_sep.add(new noderef(m_z_axis)); m_data_sep.add(new noderef(m_data_light)); m_data_sep.add(new noderef(m_data_matrix)); m_data_sep.add(new noderef(m_bins_sep)); m_data_sep.add(new noderef(m_errors_sep)); m_data_sep.add(new noderef(m_func_sep)); m_data_sep.add(new noderef(m_points_sep)); m_data_sep.add(new noderef(m_inner_frame_sep)); m_data_sep.add(new noderef(m_etc_sep)); } void update_layout(){ float XSIZ = width; float XMGL = left_margin; float XMGR = right_margin; float wData = XSIZ-XMGL-XMGR; float YSIZ = height; float YMGL = bottom_margin; float YMGU = top_margin; float hData = YSIZ-YMGL-YMGU; float ZSIZ = depth; float ZMGD = down_margin; float ZMGU = up_margin; float dData = ZSIZ-ZMGD-ZMGU; {mat4f& mtx = m_layout.mtx.value(); mtx.set_identity(); if(m_shape==xy) { // in rep primitives (0,0) is the lower left corner // of the data area square; mtx.mul_translate(-XSIZ/2+XMGL,-YSIZ/2+YMGL,0); if(data_light_on_automated.value()) m_data_light.on = false; vec3f dir(0,0,-1); m_data_light.direction = dir; } else { //xyz //printf("debug : update_layout : X : %g %g %g %g\n", // XSIZ,XMGL,XMGR,wData); //printf("debug : update_layout : Y : %g %g %g %g\n", // YSIZ,YMGL,YMGU,hData); // global transformation (to have a "lego" layout) : // translate so that the center of the scene // is the center of the data area cube; // then rotate to have lego 3D layout. mtx.mul_rotate(1,0,0,theta*fdeg2rad()); mtx.mul_rotate(0,1,0,phi*fdeg2rad()); mtx.mul_rotate(1,0,0,tau*fdeg2rad()); // To place as CERN-PAW default. // In CERN-PAW, it is the projection // which fits in the (XSIZ,XMGL,XMGR)/(YSIZ,YMGL,YMGU) // page setup. rotf r1(vec3f(1,0,0),theta * fdeg2rad()); rotf r2(vec3f(0,1,0),phi * fdeg2rad()); rotf r3(vec3f(1,0,0),tau * fdeg2rad()); rotf r = r1*r2*r3; mat4f _m; r.value(_m); float xmn = -0.5F*wData; float ymn = -0.5F*hData; float zmn = -0.5F*dData; float xmx = 0.5F*wData; float ymx = 0.5F*hData; float zmx = 0.5F*dData; box3f _box; float x,y,z; // zmn face : {x = xmn;y = ymn;z = zmn; _m.mul_3f(x,y,z); _box.extend_by(x,y,z);} {x = xmx;y = ymn;z = zmn; _m.mul_3f(x,y,z); _box.extend_by(x,y,z);} {x = xmx;y = ymx;z = zmn; _m.mul_3f(x,y,z); _box.extend_by(x,y,z);} {x = xmn;y = ymx;z = zmn; _m.mul_3f(x,y,z); _box.extend_by(x,y,z);} // zmx face : {x = xmn;y = ymn;z = zmx; _m.mul_3f(x,y,z); _box.extend_by(x,y,z);} {x = xmx;y = ymn;z = zmx; _m.mul_3f(x,y,z); _box.extend_by(x,y,z);} {x = xmx;y = ymx;z = zmx; _m.mul_3f(x,y,z); _box.extend_by(x,y,z);} {x = xmn;y = ymx;z = zmx; _m.mul_3f(x,y,z); _box.extend_by(x,y,z);} float xfac = _box.mx()[0]-_box.mn()[0]; float yfac = _box.mx()[1]-_box.mn()[1]; float zfac = _box.mx()[2]-_box.mn()[2]; //cube setup (driven by hData) : mtx.mul_scale(hData/xfac,hData/yfac,hData/zfac); mtx.mul_translate(-wData/2,-hData/2,-dData/2); //Applied first. if(data_light_on_automated.value()) m_data_light.on = true; {vec3f dir(1,-1,-10); float dx,dy,dz;dir.value(dx,dy,dz); mat4f inv; if(mtx.invert(inv)) { inv.mul_dir_3f(dx,dy,dz); m_data_light.direction = vec3f(dx,dy,dz); }} }} {mat4f& mtx = m_data_matrix.mtx.value(); mtx.set_identity(); if(m_shape==xy) { mtx.mul_scale(wData,hData,1); //z size decided with xy_depth } else if(m_shape==xyz) { mtx.mul_scale(wData,hData,dData); }} } public: void update_sg(std::ostream& a_out) { update_shape(); update_axes_data(a_out); update_background(); update_layout(); // roundtrip over plottables to check if they are valids. Done first. unsigned int nplottables = 0; unsigned int nbins = 0; unsigned int npoints = 0; unsigned int nfunc = 0; {tools_vforit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(!object->is_valid()) { *it = 0; delete object; } else { if(safe_cast(*object)) { nplottables++; nbins++; } else if(safe_cast(*object)) { nplottables++; nbins++; } else if(safe_cast(*object)) { nplottables++; npoints++; } else if(safe_cast(*object)) { nplottables++; npoints++; } else if(safe_cast(*object)) { nplottables++; nfunc++; } else if(safe_cast(*object)) { nplottables++; nfunc++; } } }} clear_cmaps(); m_bins_cmaps.resize(nbins,0); m_points_cmaps.resize(npoints,0); m_func_cmaps.resize(nfunc,0); // even if !nplottables we continue. m_infos_title_sep.clear(); m_infos_sep.clear(); m_legend_strings.clear(); bool superpose = false; /*uuuu bool superpose = superposeBins; if(superpose) { // Check compatibility of bins : if( (nbins1D<=0) || (m_shape!=XY) ) { superpose = false; } else { SbPlottableBins1D* bins = f_bins1DList[0]; int xnbin = bins->getAxisNumberOfBins(); float xmn = bins->get_axis_min(); float xmx = bins->get_axis_max(); superpose = true; for(int ibins=1;ibinsgetAxisNumberOfBins()) || (xmn!=binsloop->get_axis_min()) || (xmx!=binsloop->get_axis_max()) ) { superpose = false; break; } } if(superpose) { //Compatible bins : if(y_axis_automated) { // Correct Y axis if XY shape and superposing bins. // Get min/max float bmin,bmax; getHeight(nbins1D-1,f_bins1DList,bins1DListSwMnMx,0,bmin,bmax); bmin = bmax; for(int ibin=1;ibin=xmax) { DUMP_UPDATE_WHAT(a_out,"bad min/max x axes"); } if(ymin>=ymax) { DUMP_UPDATE_WHAT(a_out,"bad min/max y axes"); } } else if(m_shape==xyz) { if(xmin>=xmax) { DUMP_UPDATE_WHAT(a_out,"bad min/max x axes"); } if(ymin>=ymax) { DUMP_UPDATE_WHAT(a_out,"bad min/max y axes"); } if(zmin>=zmax) { DUMP_UPDATE_WHAT(a_out,"bad min/max z axes"); } } {float XSIZ = width; float XMGL = left_margin; float XMGR = right_margin; float wData = XSIZ-XMGL-XMGR; float YSIZ = height; float YMGL = bottom_margin; float YMGU = top_margin; float hData = YSIZ-YMGL-YMGU; if(m_shape==xy) { if(wData<=0) { DUMP_UPDATE_WHAT(a_out,"null w data area"); } if(hData<=0) { DUMP_UPDATE_WHAT(a_out,"null h data area"); } } else if(m_shape==xyz) { float ZSIZ = depth; float ZMGD = down_margin; float ZMGU = up_margin; float dData = ZSIZ-ZMGD-ZMGU; if(wData<=0) { DUMP_UPDATE_WHAT(a_out,"null w data area"); } if(hData<=0) { DUMP_UPDATE_WHAT(a_out,"null h data area"); } if(dData<=0) { DUMP_UPDATE_WHAT(a_out,"null d data area"); } }} float dx = xmax - xmin; float dy = ymax - ymin; float dz = zmax - zmin; rep_box boxX(xmin,dx,xlog); rep_box boxY(ymin,dy,ylog); rep_box boxZ(zmin,dz,zlog); //////////////////////////////////// /// data : ///////////////////////// //////////////////////////////////// if(m_shape==xy) { //a_out << "tools::sg::plotter::update_sg : shape xy :" << std::endl; // first data plane is at zz = _zoffset(). float zz = 0; //////////////////////////////////// /// binss ////////////////////////// //////////////////////////////////// //if(verbose) { // SoDebugError::postInfo("tools::sg;:plotter::updateChildren", // "%lu : XY : update bins",(unsigned long)this); //} {m_bins_sep.clear(); m_errors_sep.clear(); unsigned int ibins = 0; //used to get each bins style and colormap. //unsigned int ibins1D = 0; //unsigned int ibins2D = 0; tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(bins1D* b1 = safe_cast(*object)) { zz += _zoffset(); // ibins = 0 back (PAW convention). style* data_style = merge_bins_style(ibins,*object); style* _left_hatch_style = merge_left_hatch_style(ibins,*object); style* _right_hatch_style = merge_right_hatch_style(ibins,*object); style* error_style = merge_errors_style(ibins,*object); update_bins1D_xy(a_out,*b1, *data_style,*_left_hatch_style,*_right_hatch_style,*error_style,ibins, superpose,boxX,boxY,zz); if(legends_automated.value()) { m_legend_strings.push_back(object->legend()); style& _style = legend_style(m_legend_strings.size()-1); _style.color = data_style->color; _style.marker_style = data_style->marker_style; _style.marker_size = data_style->marker_size; } delete data_style; delete _left_hatch_style; delete _right_hatch_style; delete error_style; ibins++; //ibins1D++; } if(bins2D* b2 = safe_cast(*object)) { //a_out << "tools::sg::plotter::update_sg : bins2D." << std::endl; zz += _zoffset(); // ibins = 0 back (PAW convention). style* data_style = merge_bins_style(ibins,*object); update_bins2D_xy(a_out,*b2,*data_style,ibins,boxX,boxY,boxZ,zz); if(legends_automated.value()) { m_legend_strings.push_back(object->legend()); style& _style = legend_style(m_legend_strings.size()-1); _style.color = data_style->color; _style.marker_style = data_style->marker_style; _style.marker_size = data_style->marker_size; } delete data_style; ibins++; } }} //////////////////////////////////// /// funcs ////////////////////////// //////////////////////////////////// {m_func_sep.clear(); //zz = 0; // Functions in front. unsigned int ifunc = 0; //used to get each func style and colormap. tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(func1D* f1 = safe_cast(*object)) { zz += _zoffset(); style* data_style = merge_func_style(ifunc,*object); update_func1D_xy(a_out,*f1,*data_style,boxX,boxY,zz); if(legends_automated.value()) { m_legend_strings.push_back(object->legend()); style& _style = legend_style(m_legend_strings.size()-1); _style.color = data_style->color; _style.marker_style = data_style->marker_style; _style.marker_size = data_style->marker_size; } delete data_style; ifunc++; } else if(func2D* f2 = safe_cast(*object)) { zz += _zoffset(); style* data_style = merge_func_style(ifunc,*object); update_func2D_xy(a_out,*f2,ifunc,*data_style,boxX,boxY,boxZ,zz); if(legends_automated.value()) { m_legend_strings.push_back(object->legend()); style& _style = legend_style(m_legend_strings.size()-1); _style.color = data_style->color; _style.marker_style = data_style->marker_style; _style.marker_size = data_style->marker_size; } delete data_style; ifunc++; } }} //////////////////////////////////// /// pointss //////////////////////// //////////////////////////////////// {m_points_sep.clear(); unsigned int ipoints = 0; //used to get each points style and colormap. tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(points2D* p2 = safe_cast(*object)) { zz += _zoffset(); // ibins = 0 back (PAW convention). style* data_style = merge_points_style(ipoints,*object); update_points2D_xy(a_out,*p2,*data_style,boxX,boxY,zz); if(legends_automated.value()) { m_legend_strings.push_back(object->legend()); style& _style = legend_style(m_legend_strings.size()-1); _style.color = data_style->color; _style.modeling = data_style->modeling; _style.marker_style = data_style->marker_style; _style.marker_size = data_style->marker_size; _style.point_size = data_style->point_size; } delete data_style; ipoints++; } }} } if(m_shape==xyz) { //////////////////////////////////// /// binss ////////////////////////// //////////////////////////////////// {m_bins_sep.clear(); m_errors_sep.clear(); unsigned int ibins = 0; //used to get each bins style and colormap. tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(safe_cast(*object)) { ibins++; } else if(bins2D* b2 = safe_cast(*object)) { style* data_style = merge_bins_style(ibins,*object); update_bins2D_xyz(a_out,*b2,ibins,*data_style,boxX,boxY,boxZ); delete data_style; ibins++; } }} //////////////////////////////////// /// funcs ////////////////////////// //////////////////////////////////// {m_func_sep.clear(); unsigned int ifunc = 0; //used to get each func style and colormap. tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(safe_cast(*object)) { ifunc++; } else if(func2D* f2 = safe_cast(*object)) { style* data_style = merge_func_style(ifunc,*object); update_func2D_xyz(a_out,*f2,ifunc,*data_style,boxX,boxY,boxZ); delete data_style; ifunc++; } }} //////////////////////////////////// /// pointss //////////////////////// //////////////////////////////////// {m_points_sep.clear(); unsigned int ipoints = 0; //used to get each points style and colormap. tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(points3D* p3 = safe_cast(*object)) { style* data_style = merge_points_style(ipoints,*object); update_points3D_xyz(a_out,*p3,*data_style,boxX,boxY,boxZ); if(legends_automated.value()) { m_legend_strings.push_back(object->legend()); style& _style = legend_style(m_legend_strings.size()-1); _style.color = data_style->color; _style.modeling = data_style->modeling; _style.marker_style = data_style->marker_style; _style.marker_size = data_style->marker_size; _style.point_size = data_style->point_size; } delete data_style; ipoints++; } }} } //////////////////////////////////// /// axes : ///////////////////////// //////////////////////////////////// // done before update_legends() which needs // the x_axis min/max if legends_origin_unit // is unit_axis. // axes : if(m_shape==xy){ if(x_axis_enforced.value()) { update_x_axis_2D(); m_x_axis.minimum_value = x_axis_min.value(); m_x_axis.maximum_value = x_axis_max.value(); m_x_axis.is_log = x_axis_is_log.value(); m_x_axis.update_sg(a_out); // So that the grid be correct. m_x_axis.reset_touched(); } else { if(!nplottables) { m_x_axis.width = 0; } else { update_x_axis_2D(); update_axis(a_out,m_x_axis,m_x_axis_data); } } if(y_axis_enforced.value()) { update_y_axis_2D(); m_y_axis.minimum_value = y_axis_min.value(); m_y_axis.maximum_value = y_axis_max.value(); m_y_axis.is_log = y_axis_is_log.value(); m_y_axis.update_sg(a_out); // So that the grid be correct. m_y_axis.reset_touched(); } else { if(!nplottables) { m_y_axis.width = 0; } else { update_y_axis_2D(); update_axis(a_out,m_y_axis,m_y_axis_data); } } if(z_axis_enforced.value()) { update_z_axis_2D(); m_z_axis.minimum_value = z_axis_min.value(); m_z_axis.maximum_value = z_axis_max.value(); m_z_axis.is_log = z_axis_is_log.value(); m_z_axis.update_sg(a_out); // So that the grid be correct. m_z_axis.reset_touched(); } else { if(!nplottables) { m_z_axis.width = 0; } else { update_z_axis_2D(); } } } if(m_shape==xyz){ if(x_axis_enforced.value()) { update_x_axis_3D(); m_x_axis.minimum_value = x_axis_min.value(); m_x_axis.maximum_value = x_axis_max.value(); m_x_axis.is_log = x_axis_is_log.value(); m_x_axis.update_sg(a_out); // So that the grid be correct. m_x_axis.reset_touched(); } else { if(!nplottables) { m_x_axis.width = 0; } else { update_x_axis_3D(); update_axis(a_out,m_x_axis,m_x_axis_data); } } if(y_axis_enforced.value()) { update_y_axis_3D(); m_y_axis.minimum_value = y_axis_min.value(); m_y_axis.maximum_value = y_axis_max.value(); m_y_axis.is_log = y_axis_is_log.value(); m_y_axis.update_sg(a_out); // So that the grid be correct. m_y_axis.reset_touched(); } else { if(!nplottables) { m_y_axis.width = 0; } else { update_y_axis_3D(); update_axis(a_out,m_y_axis,m_y_axis_data); } } if(z_axis_enforced.value()) { update_z_axis_3D(); m_z_axis.minimum_value = z_axis_min.value(); m_z_axis.maximum_value = z_axis_max.value(); m_z_axis.is_log = z_axis_is_log.value(); m_z_axis.update_sg(a_out); // So that the grid be correct. m_z_axis.reset_touched(); } else { if(!nplottables) { m_z_axis.width = 0; } else { update_z_axis_3D(); update_axis(a_out,m_z_axis,m_z_axis_data); } } } if(nplottables) { // infos box is done before update_legends() // because legends may be placed relative to it. update_infos(a_out); } m_legend_sep.clear(); if(!legends_automated) { m_legend_strings = legends_string.values(); } update_legends(a_out); if(title_automated) { std::string _s; get_title(_s); title.value(_s); title.reset_touched(); //output field. } m_title_sep.clear(); if(nplottables) update_title(); m_title_box_sep.clear(); if(nplottables) update_title_box(); m_inner_frame_sep.clear(); if(inner_frame_enforced.value() || nplottables) { if(m_shape==xy) { update_inner_frame_XY(); } else { update_inner_frame_XYZ(); } } m_grid_sep.clear(); if(nplottables) { if(m_shape==xy) { update_grid_XY(); } else { update_grid_XYZ(); } } m_cmap_axis.width = 0; m_cmap_cells_sep.clear(); if(m_bins_cmaps.size() && m_bins_cmaps[0] && m_bins_cmaps[0]->valn()) { //major_bins update_cmap(a_out,*(m_bins_cmaps[0])); } else if(m_points_cmaps.size() && m_points_cmaps[0] && m_points_cmaps[0]->valn()) { //major_points update_cmap(a_out,*(m_points_cmaps[0])); } else if(m_func_cmaps.size() && m_func_cmaps[0] && m_func_cmaps[0]->valn()) { //major_func update_cmap(a_out,*(m_func_cmaps[0])); } update_primitives(a_out); } 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) { if(a_Sw_mn>a_Sw_mx) { a_min = 0; a_max = 0; return; } // a_Sw_mx >= a_Sw_mn. if(a_is_log && (a_Sw_mn<=0) ) { //let data_axis.adjust() do something. a_min = a_Sw_mn; a_max = a_Sw_mx; return; } float mn; if(a_is_log) { if(value_bottom_margin.value()!=0) { float log_Sw_mn = flog10(a_Sw_mn); float log_Sw_mx = flog10(a_Sw_mx); float log_mn = log_Sw_mn - (log_Sw_mx-log_Sw_mn)*value_bottom_margin; mn = fpow(10,log_mn); } else { mn = a_Sw_mn; if(a_min_visible) { // arrang so that the bin with a_Sw_mn be visible. float log_Sw_mn = flog10(a_Sw_mn); mn = fpow(10,log_Sw_mn)*(1.0f-0.4f); } } } else { if(value_bottom_margin.value()!=0) { mn = a_Sw_mn - (a_Sw_mx-a_Sw_mn)*value_bottom_margin; } else { if(a_min_visible) { // Arrange so that the bin with a_Sw_mn (if not 0) be visible. (If 0, it will be anyway on the x axis) : if(a_Sw_mn>0) { mn = 0; //PAW logic. } else if(a_Sw_mn==0) { mn = 0; //PAW logic. min bin will be anyway on x axis. } else { mn = a_Sw_mn; // min bin will be anyway on x axis. } } else { mn = a_Sw_mn; //min bin will be on x axis. } } } a_min = mn; float mx; if(a_is_log) { if(value_top_margin.value()!=0) { float log_Sw_mn = flog10(a_Sw_mn); float log_Sw_mx = flog10(a_Sw_mx); float log_mx = log_Sw_mx + (log_Sw_mx-log_Sw_mn)*value_top_margin; mx = fpow(10,log_mx); } else { mx = a_Sw_mx; //max bin will be on top of frame (then not visible if same color). } } else { mx = a_Sw_mx + (a_Sw_mx-mn)*value_top_margin; //mx = a_Sw_mx + (a_Sw_mx-a_Sw_mn)*value_top_margin; //not compatible with gopaw. } a_max = mx; } void update_axes_data(std::ostream& a_out){ m_x_axis_data.set_min_value(0); m_x_axis_data.set_max_value(0); m_x_axis_data.set_is_log(x_axis_is_log); m_y_axis_data.set_min_value(0); m_y_axis_data.set_max_value(0); m_y_axis_data.set_is_log(y_axis_is_log); m_z_axis_data.set_min_value(0); m_z_axis_data.set_max_value(0); m_z_axis_data.set_is_log(z_axis_is_log); if(!x_axis_automated) { //def = true m_x_axis_data.set_min_value(x_axis_min); m_x_axis_data.set_max_value(x_axis_max); } if(!y_axis_automated) { m_y_axis_data.set_min_value(y_axis_min); m_y_axis_data.set_max_value(y_axis_max); } if(!z_axis_automated) { m_z_axis_data.set_min_value(z_axis_min); m_z_axis_data.set_max_value(z_axis_max); } bins1D* b1; bins2D* b2; func1D* f1; func2D* f2; points2D* p2; points3D* p3; if(first_bins(b1,b2)) { if(b1) { if(x_axis_automated) { m_x_axis_data.set_min_value(b1->axis_min()); m_x_axis_data.set_max_value(b1->axis_max()); } if(y_axis_automated) { //::printf("debug : value %g %g %d : is log %d\n", // value_bottom_margin.value(),value_top_margin.value(),value_bins_with_entries.value(), // m_y_axis_data.is_log()); float Sw_mn,Sw_mx; b1->bins_Sw_range(Sw_mn,Sw_mx,value_bins_with_entries.value()); //::printf("debug : Sw %g %g\n",Sw_mn,Sw_mx); float mn,mx; get_value_axis_min_max(Sw_mn,Sw_mx,m_y_axis_data.is_log(),mn,mx,true); //::printf("debug : mn mx %g %g\n",mn,mx); m_y_axis_data.set_min_value(mn); m_y_axis_data.set_max_value(mx); m_y_axis_data.adjust(); //::printf("debug : adjusted : mn mx %g %g\n",mn,mx); } } if(b2) { if(x_axis_automated) { m_x_axis_data.set_min_value(b2->x_axis_min()); m_x_axis_data.set_max_value(b2->x_axis_max()); } if(y_axis_automated) { m_y_axis_data.set_min_value(b2->y_axis_min()); m_y_axis_data.set_max_value(b2->y_axis_max()); } if(z_axis_automated) { float Sw_mn,Sw_mx; b2->bins_Sw_range(Sw_mn,Sw_mx,value_bins_with_entries.value()); float mn,mx; get_value_axis_min_max(Sw_mn,Sw_mx,m_z_axis_data.is_log(),mn,mx,false); m_z_axis_data.set_min_value(mn); m_z_axis_data.set_max_value(mx); m_z_axis_data.adjust(); } } /*else if(f_binsList[0]->getDimension()==3) { //FIXME : should do something. } else { // Unusual case. }*/ } else if(first_points(p2,p3)) { if(p2) { if(x_axis_automated) { m_x_axis_data.set_min_value(p2->x_axis_min()); m_x_axis_data.set_max_value(p2->x_axis_max()); } if(y_axis_automated) { float ymn = p2->y_axis_min(); float ymx = p2->y_axis_max(); // For pawex22 ? //m_y_axis_data.set_min_value(ymn*1.1F); //m_y_axis_data.set_max_value(ymx*1.1F); m_y_axis_data.set_min_value(ymn); m_y_axis_data.set_max_value(ymx); } } else if(p3) { if(x_axis_automated) { m_x_axis_data.set_min_value(p3->x_axis_min()); m_x_axis_data.set_max_value(p3->x_axis_max()); } if(y_axis_automated) { m_y_axis_data.set_min_value(p3->y_axis_min()); m_y_axis_data.set_max_value(p3->y_axis_max()); } if(z_axis_automated) { m_z_axis_data.set_min_value(p3->z_axis_min()); m_z_axis_data.set_max_value(p3->z_axis_max()); } } } else if(first_func(f1,f2)) { if(f1) { if(x_axis_automated) { float xmn = f1->x_min(); float xmx = f1->x_max(); if(xmx<=xmn) { xmn = -1; xmx = 1; } m_x_axis_data.set_min_value(xmn); m_x_axis_data.set_max_value(xmx); } if(y_axis_automated) { float xmn = m_x_axis_data.min_value(); float xmx = m_x_axis_data.max_value(); unsigned int nstp = f1->x_steps(); nstp = nstp <=0 ? curve_number_of_points.value(): nstp; float df = (xmx - xmn)/nstp; bool problem = false; float vmin; if(!f1->value(xmn,vmin)) problem = true; float vmax = vmin; for(unsigned int ibin=0;ibin<=nstp;ibin++) { float xx = xmn + ibin * df; float val; if(!f1->value(xx,val)) problem = true; vmax = mx(vmax,val); vmin = mn(vmin,val); } if(problem) { a_out << "tools::sg::plotter :" << " problem when getting some function value." << std::endl; } m_y_axis_data.set_min_value(vmin); m_y_axis_data.set_max_value(vmax); m_y_axis_data.adjust(); } } else if(f2) { if(x_axis_automated) { float xmn = f2->x_min(); float xmx = f2->x_max(); if(xmx<=xmn) { xmn = -1; xmx = 1; } m_x_axis_data.set_min_value(xmn); m_x_axis_data.set_max_value(xmx); } if(y_axis_automated) { float ymn = f2->y_min(); float ymx = f2->y_max(); if(ymx<=ymn) { ymn = -1; ymx = 1; } m_y_axis_data.set_min_value(ymn); m_y_axis_data.set_max_value(ymx); } if(z_axis_automated) { float xmn = m_x_axis_data.min_value(); float xmx = m_x_axis_data.max_value(); int nx = f2->x_steps(); nx = nx <=0 ? curve_number_of_points.value() : nx; float ymn = m_y_axis_data.min_value(); float ymx = m_y_axis_data.max_value(); int ny = f2->y_steps(); ny = ny <=0 ? curve_number_of_points.value() : ny; float dfx = (xmx - xmn)/nx; float dfy = (ymx - ymn)/ny; bool problem = false; float vmin; if(!f2->value(xmn,ymn,vmin)) problem = true; float vmax = vmin; for(int jbin=ny-1;jbin>=0;jbin--) { for(int ibin=nx-1;ibin>=0;ibin--) { float xx = xmn + ibin * dfx; float yy = ymn + jbin * dfy; float val; if(!f2->value(xx,yy,val)) problem = true; vmin = mn(vmin,val); vmax = mx(vmax,val); } } if(problem) { a_out << "tools::sg::plotter :" << " problem when getting some function value." << std::endl; } m_z_axis_data.set_min_value(vmin); m_z_axis_data.set_max_value(vmax); m_z_axis_data.adjust(); } } } } void update_shape(){ m_shape = get_shape(); //uuuu if(shapeAutomated) { // shape.setValue(m_shape); //} } void update_axis(std::ostream& a_out,sg::axis& a_axis,data_axis& a_data){ a_axis.minimum_value = a_data.min_value(); a_axis.maximum_value = a_data.max_value(); a_axis.is_log = a_data.is_log(); a_axis.update_sg(a_out); // So that the grid be correct. a_axis.reset_touched(); } void update_x_axis_2D(){ float XSIZ = width; float XMGL = left_margin; float XMGR = right_margin; float wData = XSIZ-XMGL-XMGR; //m_x_axis.verbose.setValue(verbose); m_x_axis.tick_up = true; m_x_axis.width = wData; {text_style& style = m_x_axis.labels_style(); if(!style.enforced.value()) { //gopaw may enforce style. style.x_orientation = vec3f(1,0,0); style.y_orientation = vec3f(0,1,0); style.hjust = center; style.vjust = top; }} {text_style& style = m_x_axis.title_style(); style.x_orientation = vec3f(1,0,0); style.y_orientation = vec3f(0,1,0); style.hjust = m_x_axis.title_hjust; style.vjust = top;} {text_style& style = m_x_axis.mag_style(); style.hjust = left; style.vjust = bottom;} m_x_axis_matrix.set_translate(0,0,_zaxis()); } void update_y_axis_2D(){ float YSIZ = height; float YMGL = bottom_margin; float YMGU = top_margin; float hData = YSIZ-YMGL-YMGU; //m_x_axis.verbose.setValue(verbose); m_y_axis.tick_up.value(true); m_y_axis.width.value(hData); {text_style& style = m_y_axis.labels_style(); if(!style.enforced.value()) { style.x_orientation = vec3f(0,1,0); style.y_orientation = vec3f(1,0,0); style.hjust = right; style.vjust = middle; }} {text_style& style = m_y_axis.title_style(); style.x_orientation = vec3f(1,0,0); style.y_orientation = vec3f(0,-1,0); style.hjust = m_y_axis.title_hjust; style.vjust = bottom;} {text_style& style = m_y_axis.mag_style(); style.x_orientation = vec3f(0,1,0); style.y_orientation = vec3f(1,0,0); style.hjust = right; style.vjust = bottom;} {mat4f& mtx = m_y_axis_matrix.mtx.value(); mtx.set_translate(0,0,_zaxis()); mtx.mul_rotate(0,1,0,fpi()); mtx.mul_rotate(0,0,1,fhalf_pi());} } void update_z_axis_2D(){ m_z_axis.width = 0; m_z_axis_matrix.set_identity(); } void update_x_axis_3D(){ float XSIZ = width; float XMGL = left_margin; float XMGR = right_margin; float wData = XSIZ-XMGL-XMGR; //m_x_axis.verbose.setValue(verbose); m_x_axis.tick_up = false; m_x_axis.width = wData; {text_style& style = m_x_axis.labels_style(); if(!style.enforced.value()) { //style->font_name = SbFont_Hershey; //Enforce Hershey. style.x_orientation = vec3f(1,0,0); style.y_orientation = vec3f(0,1,0); style.hjust = center; style.vjust = top; }} {text_style& style = m_x_axis.title_style(); style.x_orientation = vec3f(1,0,0); style.y_orientation = vec3f(0,1,0); style.hjust = right; style.vjust = top;} //{text_style& style = m_x_axis.mag_style(); // style.hjust = left; // style.vjust = bottom;} m_x_axis_matrix.set_rotate(1,0,0,fhalf_pi()); } void update_y_axis_3D(){ float YSIZ = height; float YMGL = bottom_margin; float YMGU = top_margin; float hData = YSIZ-YMGL-YMGU; //m_x_axis.verbose.setValue(verbose); m_y_axis.tick_up = false; m_y_axis.width = hData; {text_style& style = m_y_axis.labels_style(); if(!style.enforced.value()) { //style->fontName.setValue(SbFont_Hershey); //Enforce Hershey. style.x_orientation = vec3f(-1,0,0); style.y_orientation = vec3f( 0,1,0); style.hjust = center; style.vjust = top; }} {text_style& style = m_y_axis.title_style(); style.x_orientation = vec3f(-1,0,0); style.y_orientation = vec3f( 0,1,0); style.hjust = left; style.vjust = top;} //{text_style& style = m_y_axis.mag_style(); // style.x_orientation = vec3f(0,1,0); // style.y_orientation = vec3f(1,0,0); // style.hjust = right; // style.vjust = bottom;} {mat4f& mtx = m_y_axis_matrix.mtx.value(); mtx.set_rotate(0,1,0,fhalf_pi()); mtx.mul_rotate(0,0,1,fhalf_pi());} } void update_z_axis_3D(){ float ZSIZ = depth; float ZMGD = down_margin; float ZMGU = up_margin; float dData = ZSIZ-ZMGD-ZMGU; m_z_axis.tick_up = false; m_z_axis.width = dData; {text_style& style = m_z_axis.labels_style(); if(!style.enforced.value()) { //style->fontName.setValue(SbFont_Hershey); //Enforce Hershey. style.x_orientation = vec3f(0,1,0); style.y_orientation = vec3f(1,0,0); style.hjust = right; style.vjust = middle; }} {text_style& style = m_z_axis.title_style(); style.x_orientation = vec3f(0,1,0); style.y_orientation = vec3f(1,0,0); style.hjust = right; style.vjust = bottom;} //{text_style& style = m_z_axis.mag_style(); // style.hjust = center; // style.vjust = bottom;} {mat4f& mtx = m_z_axis_matrix.mtx.value(); mtx.set_translate(0,m_y_axis.width.value(),0); mtx.mul_rotate(0,0,1,-fhalf_pi()); mtx.mul_rotate(0,1,0,-fhalf_pi());} } void update_cmap(std::ostream& a_out,const base_colormap& a_cmap){ if(!colormap_visible.value()) return; size_t valn = a_cmap.valn(); if(!valn) return; size_t coln = a_cmap.colorn(); if(!coln) return; float XSIZ = width; float XMGL = left_margin; float XMGR = right_margin; float wData = XSIZ-XMGL-XMGR; float YSIZ = height; float YMGL = bottom_margin; float YMGU = top_margin; float hData = YSIZ-YMGL-YMGU; float hcmap = hData; {mat4f& mtx = m_cmap_matrix.mtx.value(); if(m_shape==xy) { mtx = m_layout.mtx.value(); mtx.mul_translate(0,0,_zgrid()); } else { float ZSIZ = depth; float ZMGD = down_margin; float ZMGU = up_margin; float dData = ZSIZ-ZMGD-ZMGU; hcmap = dData; if(colormap_attached.value()) { mtx = m_layout.mtx.value(); mtx.mul_rotate(1,0,0,90.0F*fdeg2rad()); } else { //OpenPAW float zz = -depth*0.5f; mtx.set_translate(-XSIZ/2+XMGL,-YSIZ/2+YMGL,zz); //applied first } }} float w = XMGR*0.3F; float xx = wData+XMGR*0.1F; float zz = 0; float yy = 0; float h = hcmap/float(coln); // colored cells : {m_cmap_cells_sep.clear(); m_cmap_cells_sep.add(new normal); for(unsigned int index=0;indexcolor = a_cmap.color(index); m_cmap_cells_sep.add(mat); vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); m_cmap_cells_sep.add(vtxs); vtxs->add(xx ,yy ,zz); vtxs->add(xx + w ,yy ,zz); vtxs->add(xx + w ,yy + h ,zz); vtxs->add(xx ,yy + h ,zz); yy += h; }} // surrounding box : {rgba* mat = new rgba(); mat->color = colorf_black(); m_cmap_cells_sep.add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = line_solid; ds->line_width = 1; m_cmap_cells_sep.add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::line_strip(); m_cmap_cells_sep.add(vtxs); vtxs->add(xx ,0 ,zz); vtxs->add(xx + w ,0 ,zz); vtxs->add(xx + w ,hcmap ,zz); vtxs->add(xx ,hcmap ,zz); vtxs->add(xx ,0 ,zz);} if(!colormap_axis_visible.value()) { m_cmap_axis.width = 0; } else { // right axis : mat4f& mtx = m_cmap_axis_matrix.mtx.value(); mtx.set_identity(); zz += _zoffset()*0.01f; if(safe_cast(a_cmap)) { if(colormap_axis_labeling.value()==cells) { if((valn+1)==coln) { // ... mtx.set_translate(xx+w,h,zz); } else { mtx.set_translate(xx+w,0,zz); } } else { mtx.set_translate(xx+w,0,zz); } } else { //grey_scale,grey_scale_inverse,violet_to_red mtx.set_translate(xx+w,0,zz); } mtx.mul_rotate(0,0,1,fhalf_pi()); m_cmap_axis.title = ""; m_cmap_axis.tick_up = true; //m_cmap_axis.label_to_axis = 0.01F; //m_cmap_axis.label_height = 0.10F; //m_cmap_axis.ttf_scale = 10.0F; if(safe_cast(a_cmap)) { if(colormap_axis_labeling.value()==cells) { if((valn+1)==coln) { // ... m_cmap_axis.width = hcmap-2*h; m_cmap_axis.modeling = tick_modeling_none(); m_cmap_axis.tick_number = uint32(valn); m_cmap_axis.labels.clear(); m_cmap_axis.coords.clear(); for(unsigned int index=0;index ... m_cmap_axis.width = hcmap; m_cmap_axis.modeling = tick_modeling_none(); m_cmap_axis.tick_number = uint32(valn); m_cmap_axis.labels.clear(); m_cmap_axis.coords.clear(); for(unsigned int index=0;index(*(*it))) { update_primitive_text(*ptext); } else if(plottable_box* pbox = safe_cast(*(*it))) { update_primitive_box(a_out,*pbox); } else if(plottable_ellipse* pellipse = safe_cast(*(*it))) { update_primitive_ellipse(a_out,*pellipse); } else if(plottable_img* pimg = safe_cast(*(*it))) { update_primitive_img(a_out,*pimg); } } //} } protected: //vis bins void update_bins1D_xy(std::ostream& a_out, const bins1D& a_bins, const style& a_data_style, const style& a_left_hatch_style, const style& a_right_hatch_style, const style& a_errors_style, int a_index, /*SoStyle& aGraphicStyle, int aIndex1D, const std::vector& a_bins1DList, const SbPList& a_bins1DListSwMnMx,*/ bool /*aSuperpose*/, const rep_box& a_box_x, const rep_box& a_box_y, float a_zz){ //char sid[128]; //::sprintf(sid,"tools::sg::bins1D/0x%lx", // (unsigned long)const_cast(&a_bins)); //bool hbe = a_bins.has_entries_per_bin(); float bmin = 0; float bmax = 0; size_t xnbin = a_bins.bins(); std::vector bins(xnbin); {bool first = true; for(size_t ibin=0;ibin(bmin,val); bmax = mx(bmax,val); } }} //a_bins.bins_Sw_range(bmin,bmax,false); //modeling_profile could override errors_visible. bool errors_visible = a_errors_style.visible; if(a_data_style.visible) { painting_policy painting = a_data_style.painting; if(painting==painting_by_value) { m_bins_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_data_style.color_mapping); } else if( (painting==painting_grey_scale) || (painting==painting_grey_scale_inverse) || (painting==painting_violet_to_red) ){ {float dbins = bmax-bmin; if(dbins!=0.0F) { for(size_t index=0;index bars(xnbin); for(size_t ibin=0;ibinnlimit?true:false); //}} bool _bar_chart = false; //char sid_bin[128]; //::sprintf(sid_bin,"SbBin1D/0x%lx",(unsigned long)&a_bins); if((modeling==modeling_points())||(modeling==modeling_markers())){ //if(oneNode) { // rep_bins1D_xy_points_one(binsNode,aGraphicStyle, // bins,a_box_x,a_box_y,a_zz,std::string(sid)); //} else { rep_bins1D_xy_points(a_out,a_data_style, *(m_bins_cmaps[a_index]), bins,a_box_x,a_box_y,a_zz); //} } else if(modeling==modeling_boxes()) { //if(oneNode) { // rep_bins1D_xy_boxes_one(binsNode,aGraphicStyle, // bins,a_box_x,a_box_y,a_zz,std::string(sid)); //} else { rep_bins1D_xy_boxes(a_data_style, *(m_bins_cmaps[a_index]), bins,a_box_x,a_box_y,a_zz //,std::string(sid_bin) ); //} } else if(modeling==modeling_wire_boxes()) { //if(oneNode) { // rep_bins1D_xy_wire_boxes_one(binsNode,aGraphicStyle,barChart, // bins,a_box_x,a_box_y,a_zz,std::string(sid)); //} else { rep_bins1D_xy_wire_boxes(a_data_style,*(m_bins_cmaps[a_index]),bins,a_box_x,a_box_y,a_zz,false); //} } else if(modeling==modeling_bar_chart()) { _bar_chart = true; //if(oneNode) { // rep_bins1D_xy_wire_boxes_one(binsNode,aGraphicStyle,barChart, // bins,a_box_x,a_box_y,a_zz,std::string(sid)); //} else { rep_bins1D_xy_wire_boxes(a_data_style,*(m_bins_cmaps[a_index]),bins,a_box_x,a_box_y,a_zz,true); //} } else if(modeling==modeling_lines()){ rep_bins1D_xy_lines_one(a_data_style,bins,a_box_x,a_box_y,a_zz/*,std::string(sid)*/); } else if(modeling==modeling_curve()){ rep_bins1D_xy_curve_one(a_out,a_data_style,bins,a_box_x,a_box_y,a_zz/*,std::string(sid)*/); } else if(modeling==modeling_top_lines_boxes()) { //gopaw. pawex24, k_plus. style _style;_style.color = colorf_white(); rep_bins1D_xy_boxes(_style,*(m_bins_cmaps[a_index]),bins,a_box_x,a_box_y,a_zz); rep_bins1D_xy_top_lines(a_data_style,*(m_bins_cmaps[a_index]),bins,a_box_x,a_box_y,a_zz+_zhatch()); } else { //default modeling==modeling_top_lines() 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)*/); } hatching_policy hatching = a_data_style.hatching.value(); //::printf("debug : bins1D %d hatching : %d\n",a_index,hatching); if(hatching!=hatching_none) { // WARNING : must come AFTER rep_bins1_xy. if((hatching==hatching_right)||((hatching==hatching_left_and_right))) { //if(oneNode) { //repHatch1D_xy_one(binsNode,aRightHatchStyle,barChart,bins,a_box_x,a_box_y,a_zz+_zhatch(),std::string(sid)); //} else { rep_hatch1D_xy(a_right_hatch_style,bins,a_box_x,a_box_y,a_zz+_zhatch(),_bar_chart); //} } if((hatching==hatching_left)||((hatching==hatching_left_and_right))) { //if(oneNode) { //repHatch1D_xy_one(binsNode,aLeftHatchStyle,barChart,bins,a_box_x,a_box_y,a_zz+_zhatch(),std::string(sid)); //} else { rep_hatch1D_xy(a_left_hatch_style,bins,a_box_x,a_box_y,a_zz+_zhatch(),_bar_chart); //} } } } //end !is_profile. } //end data_style visible // Errors : if(errors_visible) { std::vector bars(xnbin); for(size_t ibin=0;ibin=int(xn))) {a_value=0;return false;} if((jbin<0)||(jbin>=int(yn))) {a_value=0;return false;} float xx_0 = a_bins.bin_lower_edge_x(ibin); //float xe_0 = a_bins.bin_upper_edge_x(ibin); float xx_1 = a_bins.bin_lower_edge_x(ibin+1); //float xe_1 = a_bins.bin_upper_edge_x(ibin+1); float yy_0 = a_bins.bin_lower_edge_y(jbin); //float ye_0 = a_bins.bin_upper_edge_y(jbin); float yy_1 = a_bins.bin_lower_edge_y(jbin+1); //float ye_1 = a_bins.bin_upper_edge_y(jbin+1); float val1 = a_bins.bin_Sw(ibin,jbin); float val2 = a_bins.bin_Sw(ibin+1,jbin); //float val3 = a_bins.getBinSumOfWeights(ibin+1,jbin+1); float val4 = a_bins.bin_Sw(ibin,jbin+1); // Interpolate : vec3f p1(xx_0,yy_0,val1); vec3f p2(xx_1,yy_0,val2); //vec3f p3(xx_1,yy_1,val3); vec3f p4(xx_0,yy_1,val4); //FIXME : case of (x,y) in (p2,p3,p4) plane _plane(p1,p2,p4); vec3f pt; line _line(vec3f(a_X,a_Y,0),vec3f(a_X,a_Y,10)); _plane.intersect(_line,pt); a_value = pt[2]; return true; } typedef struct { const func2D* m_func2D; const bins2D* m_bins2D; double m_limits[4]; double m_limits_in[4]; bool m_problem; } SbFunc; static double bins2D_to_contour(double a_X,double a_Y,void* aData) { SbFunc* func =(SbFunc*)aData; if( (a_Xm_limits_in[0])|| (a_X>func->m_limits_in[1])|| (a_Ym_limits_in[2])|| (a_Y>func->m_limits_in[3]) ) return -FLT_MAX; float value; if(!bins2D_to_func(*(func->m_bins2D),(float)a_X,(float)a_Y,value)) func->m_problem = true; return value; } static double log_bins2D_to_contour(double a_X,double a_Y,void* aData) { SbFunc* func =(SbFunc*)aData; if( (a_Xm_limits_in[0])|| (a_X>func->m_limits_in[1])|| (a_Ym_limits_in[2])|| (a_Y>func->m_limits_in[3]) ) return -FLT_MAX; float value; if(!bins2D_to_func(*(func->m_bins2D),(float)a_X,(float)a_Y,value)) func->m_problem = true; return take_log(value); } void update_bins2D_xy(std::ostream& a_out, const bins2D& a_bins, const style& a_data_style, int a_index, const rep_box& a_box_x, const rep_box& a_box_y, const rep_box& a_box_z, float a_zz){ //a_out << "tools::sg::update_bins2D_xy : begin :" << std::endl; if(!a_data_style.visible) return; //a_out << "tools::sg::update_bins2D_xy : visible :" << std::endl; unsigned int xnbin = a_bins.x_bins(); unsigned int ynbin = a_bins.y_bins(); const std::string& modeling = a_data_style.modeling; if( (modeling==modeling_curve()) || (modeling==modeling_filled_curve()) ){ a_out << "tools::sg::update_bins2D_xy : modeling_curve :" << std::endl; painting_policy painting = a_data_style.painting; float zmin = a_box_z.m_pos; float dz = a_box_z.m_width; bool zlog = a_box_z.m_log; float xmn = m_x_axis_data.min_value(); float xmx = m_x_axis_data.max_value(); float ymn = m_y_axis_data.min_value(); float ymx = m_y_axis_data.max_value(); clist_contour list_contour; //int nFir = 32; int nFir = 128; list_contour.set_first_grid(nFir,nFir); //Default : 32,32 //int nSec = 256; int nSec = 512; //slower than 256 list_contour.set_secondary_grid(nSec,nSec); //Default : 256,256. double limits[4]; // User limits : limits[0] = xmn; limits[1] = xmx; limits[2] = ymn; limits[3] = ymx; SbFunc sbFunc; sbFunc.m_func2D = 0; sbFunc.m_problem = false; sbFunc.m_bins2D = &a_bins; sbFunc.m_limits_in[0] = limits[0]; sbFunc.m_limits_in[1] = limits[1]; sbFunc.m_limits_in[2] = limits[2]; sbFunc.m_limits_in[3] = limits[3]; // Extend the grid to have some borders in order to close contours : int n = nSec - 2 * 10; double dx = (limits[1]-limits[0]) /n; double dy = (limits[3]-limits[2]) /n; limits[0] = limits[0] - 10 * dx; limits[1] = limits[1] + 10 * dx; limits[2] = limits[2] - 10 * dy; limits[3] = limits[3] + 10 * dy; sbFunc.m_limits[0] = limits[0]; sbFunc.m_limits[1] = limits[1]; sbFunc.m_limits[2] = limits[2]; sbFunc.m_limits[3] = limits[3]; list_contour.set_limits(limits); if(levels.size()) { size_t zn = levels.size(); std::vector zs(zn); for(size_t zi=0;zi zs(zn+1); float zmax = zmin + dz; double zd = (zmax-zmin)/zn; for(unsigned int zi=0;zi<=zn;zi++) zs[zi] = zmin + zi * zd; list_contour.set_planes(zs); } if(zlog) list_contour.set_field_fcn(log_bins2D_to_contour,(void*)&sbFunc); else list_contour.set_field_fcn(bins2D_to_contour,(void*)&sbFunc); #ifdef INLIBS_SG_PLOTTER_TIMING atime _start = atime::now(); #endif list_contour.ccontour::generate(); #ifdef INLIBS_SG_PLOTTER_TIMING a_out << "tools::sg::update_bins2D_xy : contour generate elapsed " << atime::elapsed(_start) << "." << std::endl; _start = atime::now(); #endif if(!list_contour.compact_strips ()) { a_out << "tools::sg::plotter::updateBins2D_XY : clist_contour::compact_strips () : failure." << std::endl; } else { #ifdef INLIBS_SG_PLOTTER_TIMING a_out << "tools::sg::update_bins2D_xy : contour compact strips elapsed " << atime::elapsed(_start) << "." << std::endl; #endif if( (painting==painting_by_level) || (painting==painting_by_value) ){ m_bins_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_data_style.color_mapping); //bool zlog = a_box_z.m_log; if(zlog) m_bins_cmaps[a_index]->set_PAW_coloring(); } else { m_bins_cmaps[a_index] = new const_colormap(a_data_style.color); } if(modeling==modeling_filled_curve()) { rep_contour_xy_filled(a_out,a_data_style, painting,*(m_bins_cmaps[a_index]), list_contour,a_box_x,a_box_y,a_box_z,a_zz /*,std::string(sid.c_str())*/); } else { rep_contour_xy(a_out,a_data_style, painting,*(m_bins_cmaps[a_index]), list_contour,a_box_x,a_box_y,a_box_z,a_zz /*,std::string(sid.c_str())*/); } } if(sbFunc.m_problem) { a_out << "tools::sg::plotter::updateFunction_XY(SbPlottableFunction2D) : " << "problem when getting some function value." << std::endl; } } else { bool hbe = a_bins.has_entries_per_bin(); float bmin = 0; float bmax = 0; std::vector bins; {bool first = true; for(int jbin=ynbin-1;jbin>=0;jbin--) { for(int ibin=xnbin-1;ibin>=0;ibin--) { if(hbe && (a_bins.bin_entries(ibin,jbin)<=0)) continue; float val = a_bins.bin_Sw(ibin,jbin); float xx = a_bins.bin_lower_edge_x(ibin); float xe = a_bins.bin_upper_edge_x(ibin); float yy = a_bins.bin_lower_edge_y(jbin); float ye = a_bins.bin_upper_edge_y(jbin); bins.push_back(rep_bin2D(xx,xe,yy,ye,val,ibin,jbin)); if(first) { first = false; bmin = val; bmax = val; } else { bmin = mn(bmin,val); bmax = mx(bmax,val); } } }} size_t number = bins.size(); //a_bins.bins_Sw_range(bmin,bmax,false); painting_policy painting = a_data_style.painting; if(painting==painting_by_value) { m_bins_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_data_style.color_mapping); } else if( (painting==painting_grey_scale) || (painting==painting_grey_scale_inverse) || (painting==painting_violet_to_red) ){ {float dbins = bmax-bmin; if(dbins!=0.0F) { for(size_t index=0;indexnlimit?true:false); }}*/ /*if(oneNode) { rep_bins2D_xy_wire_box_one(a_data_style,bins,a_box_x,a_box_y,bmin,bmax,std::string(sid)); } else {*/ rep_bins2D_xy_wire_box(a_data_style,bins,a_box_x,a_box_y,bmin,bmax,a_zz/*,std::string(sid_bin)*/); //} } else if(modeling==modeling_texts()) { //a_out << "tools::sg::update_bins2D_xy : modeling_wire_texts :" << std::endl; // one node decision : //bool oneNode = false; //{int nlimit = aGraphicStyle.multiNodeLimit.value(); // if(nlimit!=NoLimit) { // oneNode = (number>nlimit?true:false); //}} //if(oneNode) { // rep_bins2D_xy_text_one(binsNode, // aGraphicStyle, // bins,a_box_x,a_box_y,std::string(sid)); //} else { rep_bins2D_xy_text(a_data_style,bins,a_box_x,a_box_y/*,std::string(sid_bin)*/); //} } else { //default rep modeling==modeling_boxes() //a_out << "tools::sg::update_bins2D_xy : modeling_ :" << std::endl; rep_bins2D_xy_box(a_data_style,bins,a_box_x,a_box_y,bmin,bmax,a_zz); } } //end if modeling } void update_func1D_xy(std::ostream& a_out,const func1D& a_func, const style& a_style,const rep_box& a_box_x,const rep_box& a_box_y,float a_zz){ //a_out << "debug : tools::sg::plotter::update_func1D_xy : modeling " << a_style.modeling.value() << " :" << std::endl; if(!a_style.visible) return; float xmn = m_x_axis_data.min_value(); float xmx = m_x_axis_data.max_value(); unsigned int nstp = a_func.x_steps(); nstp = nstp <=0 ? curve_number_of_points.value() : nstp; float df = (xmx - xmn)/nstp; bool problem = false; std::vector points(nstp+1); for(unsigned int ibin=0;ibin<=nstp;ibin++) { float xx = xmn + ibin * df; float val; if(!a_func.value(xx,val)) problem = true; points[ibin].set_value(xx,val,a_zz); } if(problem) { a_out << "tools::sg::plotter::update_func1D_xy :" << " problem when getting some function value." << std::endl; } const std::string& modeling = a_style.modeling; if(modeling==modeling_points()){ vertices* vtxs = new vertices; std::vector& pts = vtxs->xyzs.values(); //npt*3 clip_points_2D(points,a_box_x,a_box_y,pts); if(pts.size()) { //a_out << "debug : tools::sg::plotter::update_func1D_xy :" // << " ptn " << pts.size() // << std::endl; separator* sep = new separator; m_func_sep.add(sep); rgba* mat = new rgba(); mat->color = a_style.color; sep->add(mat); draw_style* ds = new draw_style; ds->style = draw_points; ds->point_size = a_style.point_size; sep->add(ds); vtxs->mode = gl::points(); sep->add(vtxs); } else { delete vtxs; } } else if(modeling==modeling_markers()){ markers* _marks = new markers; std::vector& pts = _marks->xyzs.values(); //npt*3 clip_points_2D(points,a_box_x,a_box_y,pts); if(pts.size()) { //a_out << "debug : tools::sg::plotter::update_func1D_xy :" // << " ptn " << pts.size() // << std::endl; separator* sep = new separator; m_func_sep.add(sep); rgba* mat = new rgba(); mat->color = a_style.color; sep->add(mat); _marks->size = a_style.marker_size; _marks->style = a_style.marker_style; sep->add(_marks); } else { delete _marks; } } else { vertices* vtxs = new vertices; std::vector& pts = vtxs->xyzs.values(); //npt*3 clip_polyline_2D(points,a_box_x,a_box_y,pts); if(pts.size()) { //a_out << "debug : tools::sg::plotter::update_func1D_xy : ptn " << pts.size() << std::endl; separator* sep = new separator; m_func_sep.add(sep); rgba* mat = new rgba(); mat->color = a_style.color; sep->add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = a_style.line_pattern; ds->line_width = a_style.line_width; sep->add(ds); vtxs->mode = gl::line_strip(); sep->add(vtxs); } else { delete vtxs; } } } static double function_to_contour(double a_X,double a_Y,void* aData) { SbFunc* func = (SbFunc*)aData; if( (a_Xm_limits_in[0])|| (a_X>func->m_limits_in[1])|| (a_Ym_limits_in[2])|| (a_Y>func->m_limits_in[3]) ) return -FLT_MAX; float value; if(!func->m_func2D->value((float)a_X,(float)a_Y,value)) func->m_problem = true; return double(value); } static double log_function_to_contour(double a_X,double a_Y,void* aData) { SbFunc* func =(SbFunc*)aData; if( (a_Xm_limits_in[0])|| (a_X>func->m_limits_in[1])|| (a_Ym_limits_in[2])|| (a_Y>func->m_limits_in[3]) ) return -FLT_MAX; float value; if(!func->m_func2D->value((float)a_X,(float)a_Y,value)) func->m_problem = true; return take_log(value); } void update_func2D_xy(std::ostream& a_out,const func2D& a_func,int a_index,style& a_data_style, const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z,float a_zz){ //a_out << "debug : tools::sg::plotter::update_func2D_xy(Function2D) : begin :" << std::endl; if(!a_data_style.visible.value()) return; // std::string sid; // {std::string sp; // if(!p2sx(&a_func,sp)){} // sid = "SbFunction2D/"+sp;} const std::string& modeling = a_data_style.modeling.getValue(); painting_policy painting = a_data_style.painting; if( (modeling==modeling_curve()) || (modeling==modeling_filled_curve()) ) { //a_out << "debug : tools::sg::plotter::update_func2D_xy(Function2D) : curve." << std::endl; float zmin = a_box_z.m_pos; float dz = a_box_z.m_width; bool zlog = a_box_z.m_log; float xmn = m_x_axis_data.min_value(); float xmx = m_x_axis_data.max_value(); float ymn = m_y_axis_data.min_value(); float ymx = m_y_axis_data.max_value(); clist_contour list_contour; //int nFir = 32; int nFir = 128; list_contour.set_first_grid(nFir,nFir); //Default : 32,32 //int nSec = 256; int nSec = 512; //slower than 256 list_contour.set_secondary_grid(nSec,nSec); //Default : 256,256. double limits[4]; // User limits : limits[0] = xmn; limits[1] = xmx; limits[2] = ymn; limits[3] = ymx; SbFunc sbFunc; sbFunc.m_func2D = &a_func; sbFunc.m_problem = false; sbFunc.m_bins2D = 0; sbFunc.m_limits_in[0] = limits[0]; sbFunc.m_limits_in[1] = limits[1]; sbFunc.m_limits_in[2] = limits[2]; sbFunc.m_limits_in[3] = limits[3]; // Extend the grid to have some borders in order to close contours : int n = nSec - 2 * 10; double dx = (limits[1]-limits[0]) /n; double dy = (limits[3]-limits[2]) /n; limits[0] = limits[0] - 10 * dx; limits[1] = limits[1] + 10 * dx; limits[2] = limits[2] - 10 * dy; limits[3] = limits[3] + 10 * dy; sbFunc.m_limits[0] = limits[0]; sbFunc.m_limits[1] = limits[1]; sbFunc.m_limits[2] = limits[2]; sbFunc.m_limits[3] = limits[3]; list_contour.set_limits(limits); if(levels.getNum()) { size_t zn = levels.size(); std::vector zs(zn); for(size_t zi=0;zi zs(zn+1); float zmax = zmin + dz; double zd = (zmax-zmin)/zn; for(unsigned int zi=0;zi<=zn;zi++) zs[zi] = zmin + zi * zd; list_contour.set_planes(zs); } if(zlog) { list_contour.set_field_fcn(log_function_to_contour,(void*)&sbFunc); } else { list_contour.set_field_fcn(function_to_contour,(void*)&sbFunc); } #ifdef INLIBS_SG_PLOTTER_TIMING atime _start = atime::now(); #endif list_contour.ccontour::generate(); #ifdef INLIBS_SG_PLOTTER_TIMING a_out << "tools::sg::update_func2D_xy : contour generate elapsed " << atime::elapsed(_start) << "." << std::endl; _start = atime::now(); #endif if(!list_contour.compact_strips ()) { a_out << "tools::sg::plotter::update_func2D_xy : clist_contour::compact_strips () : failure." << std::endl; } else { #ifdef INLIBS_SG_PLOTTER_TIMING a_out << "tools::sg::update_func2D_xy : contour compact strips elapsed " << atime::elapsed(_start) << "." << std::endl; #endif if( (painting==painting_by_level) || (painting==painting_by_value) ){ m_func_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_data_style.color_mapping.value()); //bool zlog = a_box_z.m_log; if(zlog) m_func_cmaps[a_index]->set_PAW_coloring(); } else { m_func_cmaps[a_index] = new const_colormap(a_data_style.color.value()); } if(modeling==modeling_filled_curve()) { rep_contour_xy_filled(a_out,a_data_style, painting,*(m_func_cmaps[a_index]), list_contour,a_box_x,a_box_y,a_box_z,a_zz /*,std::string(sid.c_str())*/); } else { rep_contour_xy(a_out,a_data_style, painting,*(m_func_cmaps[a_index]), list_contour,a_box_x,a_box_y,a_box_z,a_zz /*,std::string(sid.c_str())*/); } } if(sbFunc.m_problem) { a_out << "tools::sg::plotter::update_func2D_xy : problem when getting some function value." << std::endl; } /* } else if(modeling==SbModeling_polygon) { int npoint = a_func.getNumberOfPoints(); if(npoint) { std::vector points(npoint); std::vector controls; for(int count=0;count=2) && (points[points.size()-1]!=points[0]) ) { points.push_back(points[0]); } project2D(points,a_box_x,a_box_y); bool editable = a_data_style.editable.getValue(); if(!editable) { clip clipper; {size_t ptn = points.size(); for(size_t index=0;index plane_xy_bot(vec3f(0, 1,0),vec3f(0,0,0)); plane plane_xy_top(vec3f(0,-1,0),vec3f(0,1,0)); plane plane_yz_left (vec3f( 1, 0,0),vec3f(0,0,0)); plane plane_yz_right(vec3f(-1, 0,0),vec3f(1,0,0)); clipper.execute(plane_xy_bot); clipper.execute(plane_xy_top); clipper.execute(plane_yz_left); clipper.execute(plane_yz_right); {int n = clipper.getNumVertices(); points.resize(n); for(int index=0;index=2) && (points[points.size()-1]!=points[0]) ) { points.push_back(points[0]); } } int ptn = points.size(); if(ptn) { vec3f* pts = &(points[0]); SoSceneGraph* separator = new SoSceneGraph(); separator->setString(sid.c_str()); functionNode->addChild(separator); SoSeparator* sep = new SoSeparator; separator->addChild(sep); sep->addChild(fStyleCache->getFilled()); sep->addChild(fStyleCache->getNormalBindingOverall()); sep->addChild(fStyleCache->getNormalZ()); sep->addChild(fStyleCache->getMaterial(a_data_style.color.getValue(),a_data_style.transparency.getValue())); SoCoordinate3* coordinate3 = new SoCoordinate3; coordinate3->point.setValues(0,ptn,pts); sep->addChild(coordinate3); SoFaceSet* faceSet = new SoFaceSet; faceSet->numVertices.set1Value(0,ptn); sep->addChild(faceSet); sep->addChild(fStyleCache->getLineStyle(SbLinePattern_solid,1)); sep->addChild(fStyleCache->getMaterial(SbColor_black,0)); //NOTE : we could simply add faceSet again ! SoLineSet* lineSet = new SoLineSet; lineSet->numVertices.set1Value(0,ptn); sep->addChild(lineSet); if(editable) { SoSeparator* sep = new SoSeparator; separator->addChild(sep); float scale = 0.05F; for(int index=0;indexaddChild(sp); SoTransform* tsf = new SoTransform(); tsf->translation.setValue(pt); tsf->scaleFactor.setValue(scale,scale,scale); sp->addChild(tsf); SoPlotter_dragger* dragger = new SoPlotter_dragger(*coordinate3,icontrol,scale,*this,const_cast(a_func),a_box_x,a_box_y,a_zz); SoTools_setDraggerColor(*dragger,SbColor_red); sp->addChild(dragger); } } } //ptn } //npoint */ } else { a_out << "tools::sg::plotter::update_func2D_xy :" << " modeling " << modeling << " does not apply on Functi on2D in XY. Valid modelings ared curve, filled_curve and polygon." << std::endl; } } void update_points2D_xy(std::ostream& a_out,const points2D& a_points,const style& a_style, const rep_box& a_box_x,const rep_box& a_box_y,float a_zz) { //a_out << "debug : tools::sg::plotter::update_points2D_xy : modeling " << a_style.modeling.value() << std::endl; if(!a_style.visible) return; size_t number = a_points.points(); if(!number) return; const std::string& modeling = a_style.modeling; if(modeling==modeling_lines()) { rep_points2D_xy_lines(a_style,a_points,a_box_x,a_box_y,a_zz); } else if(modeling==modeling_curve()) { rep_points2D_xy_curve(a_out,a_style,a_points,a_box_x,a_box_y,a_zz); } else { rep_points2D_xy_points(a_out,a_style,a_points,a_box_x,a_box_y,a_zz); } } void update_points3D_xyz(std::ostream& a_out,const points3D& a_points,const style& a_style, const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z) { //a_out << "debug : tools::sg::plotter::update_points3D_xyz : modeling " << a_style.modeling.value() << std::endl; if(!a_style.visible) return; size_t number = a_points.points(); if(!number) return; rep_points3D_xyz_points(a_out,a_style,a_points,a_box_x,a_box_y,a_box_z); } void get_title(std::string& a_s){ a_s.clear(); bins1D* b1; bins2D* b2; func1D* f1; func2D* f2; points2D* p2; points3D* p3; if(first_bins(b1,b2)) { if(b1) { a_s = b1->title(); } else if(b2) { a_s = b2->title(); } } else if(first_points(p2,p3)) { if(p2) { a_s = p2->title(); } else if(p3) { a_s = p3->title(); } } else if(first_func(f1,f2)) { if(f1) { a_s = f1->title(); } if(f2) { a_s = f2->title(); } } } void update_bins2D_xyz(std::ostream& a_out,const bins2D& a_bins,unsigned int a_index,const style& a_style, const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z){ //a_out << "tools::sg::update_bins2D_xyz : begin :" << std::endl; if(!a_style.visible) return; //a_out << "tools::sg::update_bins2D_xyz : visible :" << std::endl; unsigned int xnbin = a_bins.x_bins(); unsigned int ynbin = a_bins.y_bins(); if(!xnbin || !ynbin) return; const std::string& modeling = a_style.modeling; if(modeling==modeling_boxes()) { bool hbe = a_bins.has_entries_per_bin(); float bmin = 0; float bmax = 0; std::vector bins; {bool first = true; for(int jbin=ynbin-1;jbin>=0;jbin--) { for(int ibin=xnbin-1;ibin>=0;ibin--) { if(hbe && (a_bins.bin_entries(ibin,jbin)<=0)) continue; float val = a_bins.bin_Sw(ibin,jbin); float xx = a_bins.bin_lower_edge_x(ibin); float xe = a_bins.bin_upper_edge_x(ibin); float yy = a_bins.bin_lower_edge_y(jbin); float ye = a_bins.bin_upper_edge_y(jbin); bins.push_back(rep_bin2D(xx,xe,yy,ye,val,ibin,jbin)); if(first) { first = false; bmin = val; bmax = val; } else { bmin = mn(bmin,val); bmax = mx(bmax,val); } } }} size_t number = bins.size(); //a_bins.bins_Sw_range(bmin,bmax,false); painting_policy painting = a_style.painting; if(painting==painting_by_value) { m_bins_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_style.color_mapping); } else if( (painting==painting_grey_scale) || (painting==painting_grey_scale_inverse) || (painting==painting_violet_to_red) ){ {float dbins = bmax-bmin; if(dbins!=0.0F) { for(size_t index=0;index faces((xnbin-1)*(ynbin-1)); {bool first = true; size_t facei = 0; unsigned int xnbin_1 = xnbin-1; unsigned int ynbin_1 = ynbin-1; for(unsigned int jbin=0;jbin(bmin,val1); bmax = mx(bmax,val1); } facei++; } }} //a_bins.bins_Sw_range(bmin,bmax,false); painting_policy painting = a_style.painting; if((painting==painting_by_value)||(painting==painting_by_level)) { m_bins_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_style.color_mapping); } else { m_bins_cmaps[a_index] = new const_colormap(a_style.color); } if(painting==painting_by_level) { //gopaw rep_top_face2D_xyz_by_level(a_style,painting,*(m_bins_cmaps[a_index]), faces,a_box_x,a_box_y,a_box_z, bmin,bmax/*,SbString(sid.c_str())*/); //if(a_style.area_style.value()==area_edged) { // style gs; // gs.light_model = light_model_base_color(); // gs.line_width = 1; // rep_top_face2D_xyz_line(gs,faces,a_box_x,a_box_y,a_box_z); //} } else { //bool oneNode = false; //{int nlimit = aGraphicStyle.multiNodeLimit.getValue(); //if(nlimit!=NoLimit) { //oneNode = ((int)faces.size()>nlimit?true:false); //}} //if(oneNode) { //repTopFaces2D_xyz_one(binsNode,aGraphicStyle,faces,a_box_x,a_box_y,a_box_z,SbString(sid.c_str())); //} else { bool zlog = a_box_z.m_log; if(zlog) m_func_cmaps[a_index]->set_PAW_coloring(); rep_top_face2D_xyz(m_bins_sep,a_style,*(m_bins_cmaps[a_index]),faces,a_box_x,a_box_y,a_box_z); if(a_style.area_style.value()==area_edged) { style gs; gs.light_model = light_model_base_color(); gs.line_width = 1; rep_top_face2D_xyz_line(gs,faces,a_box_x,a_box_y,a_box_z/*,SbString(sid.c_str())*/); } if(painting==painting_uniform) { //gopaw SURF3 (s_SURF_CONT). base_colormap* cmap = new by_value_colormap(a_out,m_cmaps,a_style.color_mapping); if(cmap->colorn()<=0) { //a_out << "tools::sg::update_bins2D_xyz : bypass rep_contour_xy_filled." << std::endl; delete cmap; } else { //updateBins2D_XY(a_bins,aIndex,*gs,a_box_x,a_box_y,boxZ,1.1F); float zmin = a_box_z.m_pos; float dz = a_box_z.m_width; //bool zlog = a_box_z.m_log; float xmn = m_x_axis_data.min_value(); float xmx = m_x_axis_data.max_value(); float ymn = m_y_axis_data.min_value(); float ymx = m_y_axis_data.max_value(); clist_contour list_contour; //int nFir = 32; int nFir = 128; list_contour.set_first_grid(nFir,nFir); //Default : 32,32 //int nSec = 256; int nSec = 512; list_contour.set_secondary_grid(nSec,nSec); //Default : 256,256. double limits[4]; // User limits : limits[0] = xmn; limits[1] = xmx; limits[2] = ymn; limits[3] = ymx; SbFunc sbFunc; sbFunc.m_func2D = 0; sbFunc.m_problem = false; sbFunc.m_bins2D = &a_bins; sbFunc.m_limits_in[0] = limits[0]; sbFunc.m_limits_in[1] = limits[1]; sbFunc.m_limits_in[2] = limits[2]; sbFunc.m_limits_in[3] = limits[3]; // Extend the grid to have some borders in order to close contours : int n = nSec - 2 * 10; double dx = (limits[1]-limits[0]) /n; double dy = (limits[3]-limits[2]) /n; limits[0] = limits[0] - 10 * dx; limits[1] = limits[1] + 10 * dx; limits[2] = limits[2] - 10 * dy; limits[3] = limits[3] + 10 * dy; sbFunc.m_limits[0] = limits[0]; sbFunc.m_limits[1] = limits[1]; sbFunc.m_limits[2] = limits[2]; sbFunc.m_limits[3] = limits[3]; list_contour.set_limits(limits); //int zn = numberOfLevels.getValue(); size_t zn = cmap->colorn(); if(zn<=0) zn = 1; std::vector zs(zn+1); float zmax = zmin + dz; double zd = (zmax-zmin)/zn; for(size_t zi=0;zi<=zn;zi++) zs[zi] = zmin + zi * zd; list_contour.set_planes(zs); if(zlog) list_contour.set_field_fcn(log_bins2D_to_contour,(void*)&sbFunc); else list_contour.set_field_fcn(bins2D_to_contour,(void*)&sbFunc); list_contour.ccontour::generate(); if(!list_contour.compact_strips ()) { a_out << "tools::sg::plotter::update_bins2D_xyz : clist_contour::compact_strips () : failure." << std::endl; delete cmap; } else { delete m_bins_cmaps[a_index]; m_bins_cmaps[a_index] = cmap; //to visualize the cmap. matrix* transf = new matrix; //contour back is at ZZ - 0.01F; transf->set_translate(0,0,1.02F); transf->mul_scale(1,1,0.01F); //applied first. m_bins_sep.add(transf); style gs; gs.light_model = light_model_base_color(); //FIXME gs.transparency = 0.3F; float ZZ = 0.0F; rep_contour_xy_filled(a_out,gs,painting_by_level,*cmap,list_contour, a_box_x,a_box_y,a_box_z,ZZ/*,SbString(sid.c_str())*/); } } } //uniform } } //end if modeling } void update_func2D_xyz(std::ostream& a_out, const func2D& a_func, unsigned int a_index, const style& a_style, const rep_box& a_box_x, const rep_box& a_box_y, const rep_box& a_box_z){ //a_out << "tools::sg::plotter::update_func2D_xyz : begin :" << std::endl; if(!a_style.visible) return; //a_out << "tools::sg::plotter::update_func2D_xyz : visible :" << std::endl; float xmn = m_x_axis_data.min_value(); float xmx = m_x_axis_data.max_value(); unsigned int nx = a_func.x_steps(); nx = !nx?20:nx; float ymn = m_y_axis_data.min_value(); float ymx = m_y_axis_data.max_value(); unsigned int ny = a_func.y_steps(); ny = !ny?20:ny; float dfx = (xmx - xmn)/nx; float dfy = (ymx - ymn)/ny; //printf("debug : nx %d ny %d\n",nx,ny); std::vector faces(nx*ny); {bool problem = false; unsigned int facei = 0; float* vprev = new float[2*nx]; for(int jbin=ny-1;jbin>=0;jbin--) { float o1 = 0; float o4 = 0; for(int ibin=nx-1;ibin>=0;ibin--) { float xx = xmn + ibin * dfx; float yy = ymn + jbin * dfy; float xe = xx + dfx; float ye = yy + dfy; // Values at the corner : float val1; if(!a_func.value(xx,yy,val1)) problem = true; float val2; if(ibin==int(nx-1)) { if(!a_func.value(xe,yy,val2)) problem = true; } else { val2 = o1; } float val3,val4; if(jbin==int(ny-1)) { if(ibin==int(nx-1)) { if(!a_func.value(xe,ye,val3)) problem = true; } else { val3 = o4; } if(!a_func.value(xx,ye,val4)) problem = true; } else { val3 = vprev[2*ibin+1]; val4 = vprev[2*ibin]; } //printf("debug : %d %d : %g %g %g %g\n", // ibin,jbin, // val1,val2,val3,val4); vprev[2*ibin] = val1; vprev[2*ibin+1] = val2; o4 = val4; o1 = val1; faces[facei] = rep_top_face2D(xx,xe,yy,ye,val1,val2,val3,val4); facei++; } } delete [] vprev; if(problem) { a_out << "tools::sg::plotter::update_func2D_xyz :" << " problem when getting some function value." << std::endl; }} painting_policy painting = a_style.painting; if(painting==painting_by_value) { m_func_cmaps[a_index] = new by_value_colormap(a_out,m_cmaps,a_style.color_mapping); } else if( (painting==painting_grey_scale) || (painting==painting_grey_scale_inverse) || (painting==painting_violet_to_red) ){ float vmin = faces[0].m_v1; float vmax = faces[0].m_v1; size_t number = faces.size(); for(size_t index=0;index(vmin,vmean); vmax = mx(vmax,vmean); faces[index].m_ratio = vmean; } {float dbins = vmax-vmin; if(dbins!=0.0F) { for(size_t index=0;indexnlimit?true:false); //}} //char sid[128]; //::sprintf(sid,"SbFunction2D/0x%lx",(unsigned long)&a_func); //if(oneNode) { // repTopFaces2D_xyz_one(functionNode,a_data_style, // faces,a_box_x,a_box_y,a_box_z,std::string(sid)); //} else { bool zlog = a_box_z.m_log; if(zlog) m_func_cmaps[a_index]->set_PAW_coloring(); rep_top_face2D_xyz(m_func_sep,a_style,*(m_func_cmaps[a_index]),faces,a_box_x,a_box_y,a_box_z); } float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; float zmin = a_box_z.m_pos; float dz = a_box_z.m_width; bool zlog = a_box_z.m_log; if(func2D_borders_visible.value()) { // border X (Y=0) {separator* sep = new separator; {normal* nm = new normal; nm->vec = vec3f(0,-1,0); sep->add(nm);} {rgba* mat = new rgba(); mat->color = colorf(0.6f,0.2f,0.2f); //brown sep->add(mat);} vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); sep->add(vtxs); bool empty = true; bool problem = false; {float xx = xmn; float yy = ymn; xx = verify_log(xx,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); vtxs->add(xx,yy,0);} {float xx = xmx; float yy = ymn; xx = verify_log(xx,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); vtxs->add(xx,yy,0);} {float val; {if(!a_func.value(xmx,ymn,val)) problem = true; val = verify_log(val,zmin,dz,zlog); if(val<0) val = 0; if(val>1) val = 1;} {float xx = xmx; float yy = ymn; xx = verify_log(xx,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); vtxs->add(xx,yy,val);}} for(int ibin=nx-1;ibin>=0;ibin--) { float xx = xmn + ibin * dfx; //float xe = xx + dfx; float yy = ymn; float val; {if(!a_func.value(xx,yy,val)) problem = true; val = verify_log(val,zmin,dz,zlog); if(val<0) val = 0; if(val>1) val = 1;} xx = verify_log(xx,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); if((xx>=0)&&(xx<=1) && (yy>=0)&&(yy<=1) ) { vtxs->add(xx,yy,val); empty = false; } } if(empty) { delete sep; } else { m_func_sep.add(sep); } if(problem) { a_out << "tools::sg::plotter::update_func2D_xyz :" << " problem when getting some function value." << std::endl; }} // border Y (X=0) {separator* sep = new separator; {normal* nm = new normal; nm->vec = vec3f(-1,0,0); sep->add(nm);} {rgba* mat = new rgba(); mat->color = colorf(0.6f,0.2f,0.2f); //brown sep->add(mat);} vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); sep->add(vtxs); {float xx = xmn; float yy = ymx; xx = verify_log(xx,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); vtxs->add(xx,yy,0);} {float xx = xmn; float yy = ymn; xx = verify_log(xx,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); vtxs->add(xx,yy,0);} bool empty = true; bool problem = false; for(unsigned int jbin=0;jbin1) val = 1;} xx = verify_log(xx,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); if((xx>=0)&&(xx<=1) && (yy>=0)&&(yy<=1) ){ vtxs->add(xx,yy,val); empty = false; } } {float val; {if(!a_func.value(xmn,ymx,val)) problem = true; val = verify_log(val,zmin,dz,zlog); if(val<0) val = 0; if(val>1) val = 1;} {float xx = xmn; float yy = ymx; xx = verify_log(xx,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); vtxs->add(xx,yy,val);}} if(empty) { delete sep; } else { m_func_sep.add(sep); } if(problem) { a_out << "tools::sg::plotter::update_func2D_xyz :" << " problem when getting some function value." << std::endl; }} } //func2D_borders_visible } void update_title(){ if(!m_title_style.visible) return; if(m_shape==xyz) return; if(title.value().empty()) return; // Use the XY layout transform to position the title. // (Else we would have to compensate the 3D rotation // in order to bring the title at the right position // without rotation). //titleNode->addChild(layout); rgba* mat = new rgba(); mat->color = m_title_style.color; m_title_sep.add(mat); float text_size = title_height * m_title_style.scale; std::string font = m_title_style.font.value(); if(font==font_hershey()) { draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = m_title_style.line_pattern; ds->line_width = m_title_style.line_width; m_title_sep.add(ds); } else { m_title_sep.add(new normal); } float XSIZ = width; float XMGL = left_margin; float XMGR = right_margin; float wData = XSIZ-XMGL-XMGR; float YSIZ = height; float YMGL = bottom_margin; float YMGU = top_margin; float hData = YSIZ-YMGL-YMGU; float xx = wData/2; float yy = hData + title_to_axis; float zz = _zinfos(); vjust vjust = bottom; if(!title_up) { yy = -title_to_axis; vjust = top; } //::printf("debug : %lu : %g %g : text_size : %g : %s\n", // this,xx,yy,text_size,title.value().c_str()); vec3f TX(1,0,0); vec3f TY(0,1,0); add_string(m_title_sep, font, m_title_style.font_modeling.value(), m_title_style.encoding.value(), m_title_style.smoothing, title.value(), xx,yy,zz, //vec TX,TY, text_size, title_hjust,vjust, m_ttf); } void update_title_box(){ if(!m_title_box_style.visible) return; if(title.value().empty()) return; // same plane than infos, then in front of data and grid. float zz = _zinfos(); if(m_shape==xyz) zz = depth*0.5f; float wbox = width*title_box_width; float hbox = height*title_box_height; float xmargin = width*title_box_x_margin; //from left border float ymargin = height*title_box_y_margin; //from top border matrix* _tsf = new matrix; {float xx = -width*0.5f+wbox*0.5f+xmargin; //at left. float yy = height*0.5f-hbox*0.5F-ymargin; //at top. _tsf->set_translate(xx,yy,zz); _tsf->mul_scale(1,1,_zscale_text());} m_title_box_sep.add(_tsf); sg::text* title_box = new sg::text(m_ttf); title_box->width = wbox; title_box->height = hbox; title_box->back_area::color = m_title_box_style.back_color; title_box->color = m_title_box_style.color; title_box->font = m_title_box_style.font; title_box->font_modeling = m_title_box_style.font_modeling; title_box->encoding = m_title_box_style.encoding; title_box->line_width = m_title_box_style.line_width; //title_box->front_face = m_title_box_style.front_face; title_box->confine = true; title_box->back_area::shadow = m_title_box_style.back_shadow; title_box->strings.add(title.value()); m_title_box_sep.add(title_box); } void get_infos(std::string& a_s){ // return "[\n]\n". a_s.clear(); const std::string& opts = infos_what.value(); {bins1D* b1; bins2D* b2; func1D* f1; func2D* f2; points2D* p2; points3D* p3; if(first_bins(b1,b2)) { if(b1) { b1->infos(opts,a_s); } else if(b2) { b2->infos(opts,a_s); } } else if(first_points(p2,p3)) { if(p2) { p2->infos(opts,a_s); } else if(p3) { p3->infos(opts,a_s); } } else if(first_func(f1,f2)) { if(f1) { f1->infos(opts,a_s); } if(f2) { f2->infos(opts,a_s); } }} //look for fit infos : {tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(object->cast(s_tools_sg_fit2plot())) { if(a_s.size()) a_s += "\n"; std::string _s; object->infos(opts,_s); a_s += _s; } }} } matrix* get_infos_matrix() { if(m_infos_sep.empty()) return 0; return (matrix*)m_infos_sep[0]; //WARNING. } sg::infos_box* get_infos_node() { if(m_infos_sep.empty()) return 0; return (sg::infos_box*)m_infos_sep[1]; //WARNING. } void update_infos(std::ostream&){ if(!m_infos_style.visible) return; std::string sinfos; get_infos(sinfos); std::vector ws; words(sinfos,"\n",false,ws); size_t linen = ws.size()/2; float zz = _zinfos(); //xy if(m_shape==xyz) zz = depth*0.5f; float _height = height; if(m_shape==xyz) _height = depth; float wbox = width*infos_width; matrix* infos_title_tsf = 0; sg::text* infos_title_text = 0; std::string infos_title; if(m_infos_style.modeling==infos_modeling_ROOT()) { std::vector _ws; //to rm "Name". for(size_t index=0;indexmul_translate(xx,yy,zz); _tsf->mul_scale(1,1,_zscale_text());} //in case of having infos, the tsf is refined below. m_infos_title_sep.add(_tsf); // same params as title_box. sg::text* txt = new sg::text(m_ttf); txt->width = wbox; txt->height = hbox; txt->back_area::color = m_infos_style.back_color; txt->color = m_infos_style.color; txt->font = m_infos_style.font; txt->font_modeling = m_infos_style.font_modeling; txt->encoding = m_infos_style.encoding; txt->line_width = m_infos_style.line_width; //txt->front_face = m_infos_style.front_face; txt->confine = true; txt->back_area::shadow = m_infos_style.back_shadow; txt->hjust = center; txt->strings.add(infos_title); m_infos_title_sep.add(txt); // to refine height below. infos_title_tsf = _tsf; infos_title_text = txt; } if(sinfos.empty()) return; if(!linen) return; matrix* _tsf = new matrix; m_infos_sep.add(_tsf); sg::infos_box* infos = new sg::infos_box(m_ttf); infos->width = wbox; //infos->height is an output field, see below. infos->back_area::color = m_infos_style.back_color; infos->color = m_infos_style.color; infos->font = m_infos_style.font; infos->encoding = m_infos_style.encoding; infos->font_modeling = m_infos_style.font_modeling; infos->line_width = m_infos_style.line_width; //infos->front_face = m_infos_style.front_face; infos->back_area::shadow = m_infos_style.back_shadow; infos->border_line_width = m_infos_style.line_width; {for(size_t index=0;indexlstrings.add(name); infos->rstrings.add(value); //a_out << "debug : name " << sout(name) // << " value " << sout(value) << std::endl; }} // enforce an infos::update_sg to get infos::height // to place the box. infos->update_sg(); // if any, set infos_title height : float title_hbox = 0; if(infos_title_tsf && infos_title_text) { title_hbox = infos->height/linen; float xx = width*0.5f - wbox*0.5f - width*infos_x_margin; float yy = _height*0.5f - title_hbox*0.5F - _height*infos_y_margin; infos_title_tsf->set_identity(); infos_title_tsf->mul_translate(xx,yy,zz); infos_title_tsf->mul_scale(1,1,_zscale_text()); infos_title_text->height = title_hbox; } float hbox = infos->height; {float xx = width*0.5f -wbox*0.5f -width*infos_x_margin; float yy = _height*0.5f -hbox*0.5F - _height*infos_y_margin; yy -= title_hbox; _tsf->set_translate(xx,yy,zz); _tsf->mul_scale(1,1,_zscale_text());} m_infos_sep.add(infos); } /* void update_legends(std::ostream& a_out){ if(!legends_visible) return; if(m_legend_strings.empty()) return; if(m_legend_colors.size()!=m_legend_strings.size()) return; //m_legend_sep contains : // one global mtx // one sep per legend. {matrix* _tsf = new matrix; m_legend_sep.add(_tsf); float zz = _zinfos(); //set legends layout : if(legends_attached_to_infos) { _tsf->set_translate(0,0,zz); } else { if(legends_origin_unit==unit_axis) { // legends_origin is in axes coordinates. float x = legends_origin.value()[0]; float y = legends_origin.value()[1]; vec3f pos; if(!axis_2_vp(vec3f(x,y,0),pos)) { //SoDebugError::postInfo("SoPlotterRegion::updateChildren", // "failed for %g %g.",x,y); } else { //pos is in NDC of [0,width][0,height]. float xx = width * (-0.5f+pos[0]); float yy = height * (-0.5f+pos[1]); _tsf->set_translate(xx,yy,zz); } } else { //unit_percent // legends_origin is // the UR corner of legend region relative // to UR of plotter region. float xur = legends_origin.value()[0]; float yur = legends_origin.value()[1]; vec2f ur(1-xur,1-yur); float w = legends_size.value()[0]; float h = legends_size.value()[1]; float x = ur[0]-w; float y = ur[1]-h; float xx = width * (x-0.5f); float yy = height * (y-0.5f); _tsf->set_translate(xx,yy,zz); } }} size_t number = m_legend_strings.size(); for(size_t index=0;indexadd(_tsf); //sg::text* text = new sg::text; legend* text = new legend(m_ttf); //text->confine = true; text->strings.add(m_legend_strings[index]); sep->add(text); text->color = m_legend_colors[index]; if(legends_attached_to_infos) { // global tsf should be the identity. // legend box geometry and placement is relative // to the infos box placement and geometry : if(m_infos_style.visible) { sg::infos_box* inode = get_infos_node(); if(!inode) {delete sep;return;} matrix* imtx = get_infos_matrix(); if(!imtx) {delete sep;return;} float wbox = inode->width; float hbox = inode->height/number; text->width = wbox; text->height = hbox; _tsf->mtx = imtx->mtx; float xx = width*0.5f-wbox*0.5f; float yy = height*0.5f-inode->height-hbox*0.5f-hbox*index; _tsf->set_translate(xx,yy,0); } else { float wbox = width * legends_size.value()[0]; float hbox = (height * legends_size.value()[1])/number; text->width = wbox; text->height = hbox; float xx = width*0.5f-wbox*0.5f - width*infos_x_margin; float yy = height*0.5f-hbox*0.5F - height*infos_y_margin; yy -= hbox*index; _tsf->set_translate(xx,yy,0); } } else { //legends_size is in NDC of [0,width][0,height]. float w = width * legends_size.value()[0]; float h = height * legends_size.value()[1]; text->width = w; text->height = h/number; float xx = w * 0.5f; float yy = text->height * 0.5f; yy += text->height*(number-index-1); _tsf->set_translate(xx,yy,0); } _tsf->mul_scale(1,1,_zscale_text()); } } */ void update_legends(std::ostream& a_out) { //::printf("debug : update_legends : begin\n"); if(m_legend_strings.empty()) return; if(m_legend_strings.size()!=legends_origin.size()) return; if(legends_size.size()!=legends_origin.size()) return; if(legends_origin_unit.size()!=legends_origin.size()) return; float zz = _zinfos(); {matrix* _tsf = new matrix; _tsf->mul_scale(1,1,_zscale_text()); m_legend_sep.add(_tsf);} size_t number = m_legend_strings.size(); //::printf("debug : update_legends : 001 %lu\n",number); for(size_t index=0;indexadd(_tsf); //sg::text* text = new sg::text; legend* text = new legend(m_ttf); text->font = _style.font; text->font_modeling = _style.font_modeling; text->encoding = _style.encoding; text->strings.add(m_legend_strings[index]); text->color = _style.color; text->marker_style = _style.marker_style; text->marker_size = _style.marker_size; text->back_visible = false; sep->add(text); //legends_size is in NDC of [0,width][0,height]. float w = width * legends_size[index][0]; float h = height * legends_size[index][1]; text->width = w; text->height = h; float xxx = w * 0.5f; float yyy = h * 0.5f; if(legends_origin_unit[index]==unit_axis) { // legends_origin is in axes coordinates. float x = legends_origin[index][0]; float y = legends_origin[index][1]; vec3f pos; if(!axis_2_vp(vec3f(x,y,0),pos)) { a_out << "tools::sg::plotter::update_legends : axis_2_vp() failed for x=" << x << ", y=" << y << "." << std::endl; } else { //pos is in NDC of [0,width][0,height]. float xx = width * (-0.5f+pos[0]); float yy = height * (-0.5f+pos[1]); _tsf->set_translate(xx,yy,zz); } } else { //unit_percent // legends_origin is // the UR corner of legend region relative // to UR of plotter region. float xur = legends_origin[index][0]; float yur = legends_origin[index][1]; vec2f ur(1-xur,1-yur); float x = width*ur[0] - w; float y = height*ur[1] - h; float xx = -width*0.5f + x; float yy = -height*0.5f + y; _tsf->set_translate(xx,yy,zz); } _tsf->mul_translate(xxx,yyy,0); //applied first. } } void update_background(){ m_background_sep.clear(); if(!m_background_style.visible) return; matrix* _tsf = new matrix; m_background_sep.add(_tsf); float w2 = width*0.5F; float h2 = height*0.5F; float zz = 0; //in xy, then before first data plane at _zoffset() if(m_shape==xyz) zz = -depth*0.5f; {rgba* mat = new rgba(); if(m_background_style.line_width) { //there is a border. mat->color = m_background_style.color; //then border color ! } else { mat->color = m_background_style.back_color; } m_background_sep.add(mat); m_background_sep.add(new normal); vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); m_background_sep.add(vtxs); vtxs->add(-w2,-h2,zz); vtxs->add( w2,-h2,zz); vtxs->add( w2, h2,zz); vtxs->add(-w2, h2,zz);} if(m_background_style.line_width) { //border //WARNING : line_width should be in percent of width. //NOTE : border is done by drawing a front smaller polygon. rgba* mat = new rgba(); mat->color = m_background_style.back_color; //yes,yes ! m_background_sep.add(mat); vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); m_background_sep.add(vtxs); //float d = width*0.005; float d = width*m_background_style.line_width; zz += _zoffset()*0.5f; vtxs->add(-w2+d,-h2+d,zz); vtxs->add( w2-d,-h2+d,zz); vtxs->add( w2-d, h2-d,zz); vtxs->add(-w2+d, h2-d,zz); } } void update_inner_frame_XY(){ if(!m_inner_frame_style.visible) return; rgba* mat = new rgba(); mat->color = m_inner_frame_style.color; m_inner_frame_sep.add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = m_inner_frame_style.line_pattern; ds->line_width = m_inner_frame_style.line_width; m_inner_frame_sep.add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::line_strip(); m_inner_frame_sep.add(vtxs); float zz = _zgrid(); vtxs->add(0,0,zz); vtxs->add(1,0,zz); vtxs->add(1,1,zz); vtxs->add(0,1,zz); vtxs->add(0,0,zz); } void update_inner_frame_XYZ(){ if(!m_inner_frame_style.visible) return; rgba* mat = new rgba(); mat->color = m_inner_frame_style.color; m_inner_frame_sep.add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = m_inner_frame_style.line_pattern; ds->line_width = m_inner_frame_style.line_width; m_inner_frame_sep.add(ds); vertices* ls = new vertices; ls->mode = gl::lines(); m_inner_frame_sep.add(ls); // z bottom : ls->add(0,0,0);ls->add(1,0,0); ls->add(1,0,0);ls->add(1,1,0); ls->add(1,1,0);ls->add(0,1,0); ls->add(0,1,0);ls->add(0,0,0); // z top : ls->add(0,0,1);ls->add(1,0,1); ls->add(1,0,1);ls->add(1,1,1); ls->add(1,1,1);ls->add(0,1,1); ls->add(0,1,1);ls->add(0,0,1); // sides along z : ls->add(0,0,0);ls->add(0,0,1); ls->add(1,0,0);ls->add(1,0,1); ls->add(1,1,0);ls->add(1,1,1); ls->add(0,1,0);ls->add(0,1,1); } void update_grid_XY(){ if(!m_grid_style.visible) return; unsigned int number = m_x_axis.tick_number + m_y_axis.tick_number; if(number<=0) return; bool draw_vertical = true; bool draw_horizontal = true; if(m_grid_style.options.value()=="vertical") draw_horizontal = false; if(m_grid_style.options.value()=="horizontal") draw_vertical = false; rgba* mat = new rgba(); mat->color = m_grid_style.color; m_grid_sep.add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = line_solid; ds->line_width = m_grid_style.line_width; m_grid_sep.add(ds); float zz = _zgrid(); vertices* vtxs = new vertices; vtxs->mode = gl::lines(); m_grid_sep.add(vtxs); std::vector& pts = vtxs->xyzs.values(); bool is_solid = m_grid_style.line_pattern.value()==line_solid; if(draw_vertical) { float _width = m_y_axis.width; float xx; {size_t _number = m_x_axis.coords.size(); if(is_solid) { pts.reserve(_number*6); for(size_t count=0;count<_number;count++) { xx = m_x_axis.coords[count]; vtxs->add(xx, 0 ,zz); vtxs->add(xx, _width,zz); } } else { pts.reserve(_number*100*6); for(size_t count=0;count<_number;count++) { xx = m_x_axis.coords[count]; vtxs->add_dashed_line(xx,0,zz,xx,_width,zz,100); } }} if(m_x_axis.is_log) { size_t _number = m_x_axis.sub_coords.size(); if(is_solid) { pts.reserve(_number*6); for(size_t count=0;count<_number;count++) { xx = m_x_axis.sub_coords[count]; vtxs->add(xx, 0 ,zz); vtxs->add(xx,_width,zz); } } else { pts.reserve(_number*100*6); for(size_t count=0;count<_number;count++) { xx = m_x_axis.sub_coords[count]; vtxs->add_dashed_line(xx,0,zz,xx,_width,zz,100); } } } } if(draw_horizontal) { float _width = m_x_axis.width; float yy; {size_t _number = m_y_axis.coords.size(); if(is_solid) { pts.reserve(_number*6); for(size_t count=0;count<_number;count++) { yy = m_y_axis.coords[count]; vtxs->add(0,yy ,zz); vtxs->add(_width,yy,zz); } } else { pts.reserve(_number*100*6); for(size_t count=0;count<_number;count++) { yy = m_y_axis.coords[count]; vtxs->add_dashed_line(0,yy,zz,_width,yy,zz,100); } }} if(m_y_axis.is_log) { size_t _number = m_y_axis.sub_coords.size(); if(is_solid) { pts.reserve(_number*6); for(size_t count=0;count<_number;count++) { yy = m_y_axis.sub_coords[count]; vtxs->add(0,yy, zz); vtxs->add(_width,yy,zz); } } else { pts.reserve(_number*100*6); for(size_t count=0;count<_number;count++) { yy = m_y_axis.sub_coords[count]; vtxs->add_dashed_line(0,yy,zz,_width,yy,zz,100); } } } } } void update_grid_XYZ(){ if(!m_grid_style.visible) return; rgba* mat = new rgba(); mat->color = m_grid_style.color; m_grid_sep.add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = m_grid_style.line_pattern; ds->line_width = m_grid_style.line_width; m_grid_sep.add(ds); /* vertices* vtxs = new vertices; vtxs->mode = gl::line_strip(); m_grid_sep.add(vtxs); float z = 0.5F; vtxs->add(0,0,z); vtxs->add(1,0,z); vtxs->add(1,1,z); vtxs->add(0,1,z); vtxs->add(0,0,z); */ /* int ntick = m_z_axis.tickNumber; if(ntick<=0) return; SoSeparator* sep = (SoSeparator*)gridSeparator.value(); sep->addChild(fStyleCache->getMaterial (style->color.value(), style->transparency.value())); sep->addChild(getLineStyle(*style)); vec3f* points = new vec3f[4 * ntick]; int pos = 0; for(int count=0;count0) { SoCoordinate3* coordinate3 = new SoCoordinate3; int32_t pointn = pos; coordinate3->point.setValues(0,pointn,points); sep->addChild(coordinate3); SoLineSet* lineSet = new SoLineSet; int segmentn = pointn/2; int32_t* vertices = new int32_t[segmentn]; for (int count=0;countnumVertices.setValues(0,segmentn,vertices); delete [] vertices; sep->addChild(lineSet); } delete [] points; */ } protected: //rep //////////////////////////////////////////////////////////////////////////// // reps xy ///////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// void rep_bins1D_xy_top_lines(const style& a_style, const base_colormap& a_cmap, const std::vector& a_bins, const rep_box& a_box_x, const rep_box& a_box_y, float a_zz/*, const std::string& aID*/){ painting_policy painting = a_style.painting; float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; float y0 = 0; y0 = verify_log(y0,ymin,dy,ylog); if(y0<0) y0 = 0; if(y0>1) y0 = 1; separator* _sep = new separator(); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = a_style.line_pattern; ds->line_width = a_style.line_width; _sep->add(ds); bool empty = true; colorf clr; float yp = 0; size_t xnbin = a_bins.size(); for(size_t index=0;index1) continue; if(xx<0) xx = 0; if(xe>1) xe = 1; if(y<0) y = 0; if(y>1) y = 1; separator* sep = new separator(); _sep->add(sep); /*uuu a_bins[index].fSeparator = sep; {char s[128]; //::sprintf(s,"%d",index); sep->setInfos(s); //::sprintf(s,"/0x%lx",(unsigned long)sep->getInfos()); std::string sid = aID; sid += std::string(s); sep->setString(sid);}*/ if(painting==painting_by_value) { a_cmap.get_color(val,clr); } else if( (painting==painting_grey_scale) || (painting==painting_grey_scale_inverse) || (painting==painting_violet_to_red) ){ a_cmap.get_color(a_bins[index].m_ratio,clr); } else { clr = a_style.color; } rgba* mat = new rgba(); mat->color = clr; sep->add(mat); vertices* vtxs = new vertices; vtxs->mode = gl::line_strip(); sep->add(vtxs); vtxs->add(xx,yp,a_zz); vtxs->add(xx,y,a_zz); vtxs->add(xe,y,a_zz); if(index==xnbin-1){ vtxs->add(xe,y0,a_zz); } empty = false; yp = y; } if(empty) { delete _sep; } else { m_bins_sep.add(_sep); } } void rep_bins1D_xy_points(std::ostream& a_out, const style& a_style, const base_colormap& a_cmap, const std::vector& a_bins, const rep_box& a_box_x, const rep_box& a_box_y, float a_zz/*, const std::string& aID*/){ //::printf("debug : tools::sg::plotter::rep_bins1D_xy_points : begin\n"); float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; painting_policy painting = a_style.painting; separator* _sep = new separator(); if(a_style.modeling==modeling_points()) { draw_style* ds = new draw_style; ds->style = draw_points; ds->point_size = a_style.point_size; _sep->add(ds); } bool empty = true; colorf clr; size_t xnbin = a_bins.size(); for(size_t index=0;index1)||(y<0)||(y>1)) continue; //::printf("debug : tools::sg::plotter::rep_bins1D_xy_points : x %g, y %g, val %g\n",x,y,val); separator* sep = new separator(); _sep->add(sep); //a_bins[index].fSeparator = sep; //{char s[128]; // ::sprintf(s,"%d",index); // sep->setInfos(s); // ::sprintf(s,"/0x%lx",(unsigned long)sep->getInfos()); // std::string sid = aID; // sid += std::string(s); // sep->setString(sid);} if(painting==painting_by_value) { a_cmap.get_color(val,clr); } else if( (painting==painting_grey_scale) || (painting==painting_grey_scale_inverse) || (painting==painting_violet_to_red) ){ a_cmap.get_color(a_bins[index].m_ratio,clr); } else { clr = a_style.color; } rgba* mat = new rgba(); mat->color = clr; sep->add(mat); if(a_style.modeling==modeling_points()) { vertices* vtxs = new vertices; vtxs->mode = gl::points(); vtxs->add(x,y,a_zz); sep->add(vtxs); } else if(a_style.modeling==modeling_markers()) { markers* _marks = new markers; _marks->size = a_style.marker_size; _marks->style = a_style.marker_style; _marks->add(x,y,a_zz); sep->add(_marks); } else { a_out << "tools::sg::plotter::rep_bins1D_xy_points :" << " bad modeling style " << tools::sout(a_style.modeling) << std::endl; delete _sep; return; } empty = false; } if(empty) { delete _sep; } else { m_bins_sep.add(_sep); } } void rep_bins1D_xy_boxes(const style& a_style, const base_colormap& a_cmap, const std::vector& a_bins, const rep_box& a_box_x, const rep_box& a_box_y, float a_zz //,const std::string& aID ){ painting_policy painting = a_style.painting; float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; separator* _sep = new separator(); _sep->add(new normal); bool empty = true; colorf clr; tools_vforcit(rep_bin1D,a_bins,it) { const rep_bin1D& rbin = *it; float xx = rbin.m_x_min; float xe = rbin.m_x_max; float yy = rbin.m_v_min; float ye = rbin.m_val; if(ye1) continue; if(xe<0) continue; if(xx<0) xx = 0; if(xe>1) xe = 1; if(yy>1) continue; if(ye<0) continue; if(yy<0) yy = 0; if(ye>1) ye = 1; //FIXME if(ye<=yy) continue; //Else we shall have a tessellation error. separator* sep = new separator(); _sep->add(sep); //a_bins[index].fSeparator = sep; //{char s[128]; //::sprintf(s,"%d",index); //sep->setInfos(s); //::sprintf(s,"/0x%lx",(unsigned long)sep->getInfos()); //std::string sid = aID; //sid += std::string(s); //sep->setString(sid);} if(painting==painting_by_value) { a_cmap.get_color(val,clr); } else if( (painting==painting_grey_scale) || (painting==painting_grey_scale_inverse) || (painting==painting_violet_to_red) ){ a_cmap.get_color(rbin.m_ratio,clr); } else { clr = a_style.color; } rgba* mat = new rgba(); mat->color = clr; sep->add(mat); vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); sep->add(vtxs); vtxs->add(xx,yy,a_zz); vtxs->add(xe,yy,a_zz); vtxs->add(xe,ye,a_zz); vtxs->add(xx,ye,a_zz); empty = false; } if(empty) { delete _sep; } else { m_bins_sep.add(_sep); } } void rep_bins1D_xy_wire_boxes(const style& a_style, const base_colormap& a_cmap, const std::vector& a_bins, const rep_box& a_box_x,const rep_box& a_box_y, float a_zz, bool a_bar_chart/*, const std::string& aID*/){ painting_policy painting = a_style.painting; float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; separator* _sep = new separator(); bool empty = true; colorf clr; tools_vforcit(rep_bin1D,a_bins,it) { const rep_bin1D& rbin = *it; float xx = rbin.m_x_min; float xe = rbin.m_x_max; float yy = rbin.m_v_min; float ye = rbin.m_val; if(ye1) continue; if(xe<0) continue; if(xx<0) xx = 0; if(xe>1) xe = 1; if(yy>1) continue; if(ye<0) continue; if(yy<0) yy = 0; if(ye>1) ye = 1; separator* sep = new separator(); _sep->add(sep); //{char s[128]; //::sprintf(s,"%d",index); //sep->setInfos(s); //::sprintf(s,"/0x%lx",(unsigned long)sep->getInfos()); //std::string sid = aID; //sid += std::string(s); //sep->setString(sid);} if(painting==painting_by_value) { a_cmap.get_color(val,clr); } else if( (painting==painting_grey_scale) || (painting==painting_grey_scale_inverse) || (painting==painting_violet_to_red) ){ a_cmap.get_color(rbin.m_ratio,clr); } else { clr = a_style.color; } rgba* mat = new rgba(); mat->color = clr; sep->add(mat); vertices* vtxs = new vertices; vtxs->mode = gl::line_strip(); sep->add(vtxs); vtxs->add(xx,yy,a_zz); vtxs->add(xe,yy,a_zz); vtxs->add(xe,ye,a_zz); vtxs->add(xx,ye,a_zz); vtxs->add(xx,yy,a_zz); empty = false; } if(empty) { delete _sep; } else { m_bins_sep.add(_sep); } } void rep_bins1D_xy_lines_one(const style& a_style,const std::vector& a_bins, const rep_box& a_box_x,const rep_box& a_box_y,float a_zz/*,const SbString& aID*/) { // Draw lines connecting top middle of bins. //::printf("debug : rep_bins2D_lines_one\n"); size_t xnbin = a_bins.size(); std::vector points(xnbin); for(size_t index=0;index& pts = vtxs->xyzs.values(); //npt*3 clip_polyline_2D(points,a_box_x,a_box_y,pts); if(pts.size()) { sg::separator* separator = new sg::separator; //separator->setString(aID); rgba* mat = new rgba(); mat->color = a_style.color; separator->add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = a_style.line_pattern; ds->line_width = a_style.line_width; separator->add(ds); vtxs->mode = gl::line_strip(); separator->add(vtxs); m_bins_sep.add(separator); } else { delete vtxs; } } void rep_bins1D_xy_curve_one(std::ostream& a_out,const style& a_style,const std::vector& a_bins, const rep_box& a_box_x,const rep_box& a_box_y,float a_zz/*,const SbString& aID*/){ //::printf("debug : rep_bins1D_curve_one\n"); size_t number = a_bins.size(); if(!number) return; double* xs = new double[number]; double* ys = new double[number]; float x,y; for(size_t index=0;index points(nstp+1); for(unsigned int ibin=0;ibin<=nstp;ibin++) { float xx = xmn + ibin * step; double val = _spline.eval(xx); points[ibin].set_value(xx,float(val),a_zz); } vertices* vtxs = new vertices; std::vector& pts = vtxs->xyzs.values(); //npt*3 clip_polyline_2D(points,a_box_x,a_box_y,pts); if(pts.size()) { sg::separator* separator = new sg::separator; //separator->setString(aID); rgba* mat = new rgba(); mat->color = a_style.color; separator->add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = a_style.line_pattern; ds->line_width = a_style.line_width; separator->add(ds); vtxs->mode = gl::line_strip(); separator->add(vtxs); m_bins_sep.add(separator); } else { delete vtxs; } } void rep_bins2D_xy_box(const style& a_style,const std::vector& a_bins, const rep_box& a_box_x,const rep_box& a_box_y,float a_bmin,float a_bmax,float a_zz) { // Draw box of size proportionnal to bin value. //std::cout << "debug : tools::sg::plotter::rep_bins2D_xy_box" << std::endl; separator* _sep = new separator(); _sep->add(new normal); rgba* mat = new rgba(); mat->color = a_style.color; _sep->add(mat); float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; bool empty = true; float range = a_bmax - a_bmin; tools_vforcit(rep_bin2D,a_bins,it) { const rep_bin2D& rbin = *it; float xx = rbin.m_x_min; float xe = rbin.m_x_max; float yy = rbin.m_y_min; float ye = rbin.m_y_max; float val = rbin.m_val; float xsize,ysize; if(range>0) { // If val = bmax, the box maps the cell. xsize = (val - a_bmin) * (xe - xx) / range; ysize = (val - a_bmin) * (ye - yy) / range; } else { //If range is 0. ; then all bins that have // entries have same values. Draw box xdbin * ydbin. xsize = xe - xx; ysize = ye - yy; } xx = xx + ((xe-xx) - xsize)/2; xe = xx + xsize; yy = yy + ((ye-yy) - ysize)/2; ye = yy + ysize; xx = verify_log(xx ,xmin,dx ,xlog); xe = verify_log(xe ,xmin,dx ,xlog); yy = verify_log(yy ,ymin,dy ,ylog); ye = verify_log(ye ,ymin,dy ,ylog); // Clipping : if(xx>1) continue; if(xe<0) continue; if(xx<0) xx = 0; if(xe>1) xe = 1; if(yy>1) continue; if(ye<0) continue; if(yy<0) yy = 0; if(ye>1) ye = 1; //sg::separator* sep = new separator(); //_sep->add(sep); /*{char s[128]; //::sprintf(s,"%d %d",rbin.fI,rbin.fJ); sep->setInfos(s); //::sprintf(s,"/0x%lx",(unsigned long)sep->getInfos()); std::string sid = aID; sid += std::string(s); sep->setString(sid);}*/ vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); //sep->add(vtxs); _sep->add(vtxs); vtxs->add(xx,yy,a_zz); vtxs->add(xe,yy,a_zz); vtxs->add(xe,ye,a_zz); vtxs->add(xx,ye,a_zz); empty = false; } if(empty) { delete _sep; } else { m_bins_sep.add(_sep); } } void rep_bins2D_xy_wire_box(const style& a_style, const std::vector& a_bins, const rep_box& a_box_x,const rep_box& a_box_y, float a_bmin,float a_bmax,float a_zz /*,const SbString& aID*/){ // Draw box of size proportionnal to bin value. sg::separator* separator = new sg::separator; rgba* mat = new rgba(); mat->color = a_style.color; separator->add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = a_style.line_pattern; ds->line_width = a_style.line_width; separator->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::lines(); separator->add(vtxs); bool empty = true; float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; float range = a_bmax - a_bmin; size_t number = a_bins.size(); for(size_t index=0;index0) { // If val = bmax, the box maps the cell. xsize = (val - a_bmin) * (xe - xx) / range; ysize = (val - a_bmin) * (ye - yy) / range; } else { //If range is 0. ; then all bins that have // entries have same values. Draw box xdbin * ydbin. xsize = xe - xx; ysize = ye - yy; } xx = xx + ((xe-xx) - xsize)/2; xe = xx + xsize; yy = yy + ((ye-yy) - ysize)/2; ye = yy + ysize; xx = verify_log(xx ,xmin,dx ,xlog); xe = verify_log(xe ,xmin,dx ,xlog); yy = verify_log(yy ,ymin,dy ,ylog); ye = verify_log(ye ,ymin,dy ,ylog); // Clipping : if(xx>1) continue; if(xe<0) continue; if(xx<0) xx = 0; if(xe>1) xe = 1; if(yy>1) continue; if(ye<0) continue; if(yy<0) yy = 0; if(ye>1) ye = 1; //::printf("debug : zzzzuu : %g %g %g %g\n",xx,xe,yy,ye); //{char s[128]; // ::sprintf(s,"%d %d",a_bins[index].fI,a_bins[index].fJ); // sep->setInfos(s);} //{std::string sp; // if(!p2sx(sep->getInfos(),sp)){} // std::string sid(aID.getString()); // sid += "/"+sp; // sep->setString(sid.c_str());} //vertices* vtxs = new vertices; //vtxs->mode = gl::line_strip(); //separator->add(vtxs); //vtxs->add(xx,yy,a_zz); //vtxs->add(xe,yy,a_zz); //vtxs->add(xe,ye,a_zz); //vtxs->add(xx,ye,a_zz); //vtxs->add(xx,yy,a_zz); vtxs->add(xx,yy,a_zz); vtxs->add(xe,yy,a_zz); vtxs->add(xe,yy,a_zz); vtxs->add(xe,ye,a_zz); vtxs->add(xe,ye,a_zz); vtxs->add(xx,ye,a_zz); vtxs->add(xx,ye,a_zz); vtxs->add(xx,yy,a_zz); empty = false; } if(empty) { delete separator; } else { m_bins_sep.add(separator); } } void rep_bins2D_xy_solid(const style& a_style,const base_colormap& a_cmap,const std::vector& a_bins, const rep_box& a_box_x,const rep_box& a_box_y,float a_zz) { painting_policy painting = a_style.painting; separator* _sep = new separator(); _sep->add(new normal); float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; bool empty = true; colorf clr; tools_vforcit(rep_bin2D,a_bins,it) { const rep_bin2D& rbin = *it; float xx = rbin.m_x_min; float xe = rbin.m_x_max; float yy = rbin.m_y_min; float ye = rbin.m_y_max; float val = rbin.m_val; xx = verify_log(xx ,xmin,dx ,xlog); xe = verify_log(xe ,xmin,dx ,xlog); yy = verify_log(yy ,ymin,dy ,ylog); ye = verify_log(ye ,ymin,dy ,ylog); // Clipping : if(xx>1) continue; if(xe<0) continue; if(xx<0) xx = 0; if(xe>1) xe = 1; if(yy>1) continue; if(ye<0) continue; if(yy<0) yy = 0; if(ye>1) ye = 1; if(painting==painting_by_value) { a_cmap.get_color(val,clr); } else if( (painting==painting_grey_scale) || (painting==painting_grey_scale_inverse) || (painting==painting_violet_to_red) ){ a_cmap.get_color(rbin.m_ratio,clr); } else { clr = a_style.color; } rgba* mat = new rgba(); mat->color = clr; _sep->add(mat); vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); //sep->add(vtxs); _sep->add(vtxs); vtxs->add(xx,yy,a_zz); vtxs->add(xe,yy,a_zz); vtxs->add(xe,ye,a_zz); vtxs->add(xx,ye,a_zz); empty = false; } if(empty) { delete _sep; } else { m_bins_sep.add(_sep); } } void rep_bins2D_xy_random_one(const style& a_style,const std::vector& a_bins, const rep_box& a_box_x,const rep_box& a_box_y,float a_bmin,float a_bmax,float a_zz /*,const SbString& aID*/){ //::printf("debug : rep_bins2D_xy_random_one\n"); sg::separator* separator = new sg::separator; rgba* mat = new rgba(); mat->color = a_style.color; separator->add(mat); draw_style* ds = new draw_style; ds->style = draw_points; ds->point_size = a_style.point_size; separator->add(ds); float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; // Draw for each bins a number of random // points proportiannal to bins range. float range = a_bmax - a_bmin; bool empty = true; size_t number = a_bins.size(); for(size_t index=0;index0. ? (int)((val - a_bmin)*(nmax-nmin)/range + nmin):1; if(npt>0) { vertices* vtxs = new vertices; vtxs->mode = gl::points(); separator->add(vtxs); float xdbin = xe - xx; float ydbin = ye - yy; for(int count=0;count=0)&&(xxx<=1) && (yyy>=0)&&(yyy<=1) ) { vtxs->add(xxx,yyy,a_zz); empty = false; } } } }//end for if(empty) { delete separator; } else { m_bins_sep.add(separator); } } void rep_bins2D_xy_text( const style& //a_style ,const std::vector& //a_bins ,const rep_box& //a_box_x ,const rep_box& //a_box_y //,const SbString& aID ){ //Draw box and text for number of entries. ::printf("debug : rep_bins2D_xy_text : dummy\n"); /* sg::separator* separator = new sg::separator; //bool drawWireBoxe = false; bool empty = true; float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; vec3f points[5]; for(unsigned int index=0;index1) continue; if(xe<0) continue; if(xx<0) xx = 0; if(xe>1) xe = 1; if(yy>1) continue; if(ye<0) continue; if(yy<0) yy = 0; if(ye>1) ye = 1; char sval[32]; //::sprintf (sval,"%d",ival); SbString sbval(sval); int charn = sbval.getLength(); if(charn<=0) continue; SoSceneGraph* sep = new SoSceneGraph; separator->addChild(sep); {char s[128]; //::sprintf(s,"%d %d",a_bins[index].fI,a_bins[index].fJ); sep->setInfos(s);} {std::string sp; if(!p2sx(sep->getInfos(),sp)){} std::string sid(aID.getString()); sid += "/"+sp; sep->setString(sid.c_str());} SoMaterial* material = fStyleCache->getMaterial(a_style.color.getValue(), a_style.transparency.getValue()); sep->addChild(material); sep->addChild(getLineStyle(a_style)); float dx = xe-xx; float dy = ye-yy; if(drawWireBoxe) { LIST_SET(points,0,xx,yy,0); LIST_SET(points,1,xe,yy,0); LIST_SET(points,2,xe,ye,0); LIST_SET(points,3,xx,ye,0); LIST_SET(points,4,xx,yy,0); coordIndex[0] = icoord + 0; coordIndex[1] = icoord + 1; coordIndex[2] = icoord + 2; coordIndex[3] = icoord + 3; coordIndex[4] = icoord + 4; coordIndex[5] = SO_END_LINE_INDEX; coordinate3->point.setValues(icoord,5,points); icoord += 5; SoIndexedLineSet* lineSet = new SoIndexedLineSet; lineSet->coordIndex.setValues(0,6,coordIndex); sep->addChild(lineSet); } float x = xx + 0.1F * dx; float y = yy + 0.1F * dy; float z = 0; float w = dx * 0.5F; float h = dy * 0.5F; SoTransform* transform = new SoTransform; transform->scaleFactor.setValue(vec3f(w/charn,h,1)); transform->translation.setValue(x,y,z); sep->addChild(transform); SoTextHershey* text = new SoTextHershey; text->string.setValue(sbval); sep->addChild (text); empty = false; } if(empty) { delete separator; } else { m_bins_sep.add(separator); } */ } void rep_contour_xy(std::ostream& a_out,const style& a_style,painting_policy a_painting, const base_colormap& a_cmap,clist_contour& a_contour, const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z,float a_zz /*,const std::string& aID*/){ //a_out << "debug : rep_contour_xy :" << std::endl; float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; float zmin = a_box_z.m_pos; float dz = a_box_z.m_width; //bool zlog = a_box_z.m_log; sg::separator* separator = new sg::separator; //separator->setString(aID); draw_style* ds = new draw_style; ds->style.value(draw_lines); ds->line_pattern.value(a_style.line_pattern); ds->line_width.value(a_style.line_width); separator->add(ds); atb_vertices* vtxs = new atb_vertices; vtxs->mode = gl::lines(); //segments separator->add(vtxs); bool empty = true; for (unsigned int i=0;i1) continue; if(zz<0) continue; colorf _color; if(a_painting==painting_by_value) { a_cmap.get_color(val,_color); } else if(a_painting==painting_by_level) { size_t icol = a_cmap.colorn() ? (i % a_cmap.colorn()) :0; _color = a_cmap.color(icol); } else { _color = a_style.color; } tools_lforcit(cline_strip*,*pStripList,pos) { cline_strip* pStrip = (*pos); if(!pStrip) { a_out << "tools::sg;:plotter::rep_contour_xy : problem with contour." << std::endl; delete separator; return; } if (pStrip->empty()) continue; //// putting point at start and end of strip //// retreiving index //unsigned int index=pStrip->front(); //double xb=a_contour.get_xi(index); //double yb=a_contour.get_yi(index); //// retreiving index ////glColor4f(0,0,1,.8f); //index=pStrip->back(); //double xe=a_contour.get_xi(index); //double ye=a_contour.get_yi(index); bool first = true; float xprev = 0; float yprev = 0; float xx,yy; tools_lforcit(unsigned int,*pStrip,pos2) { xx = (float)a_contour.get_xi(*pos2); yy = (float)a_contour.get_yi(*pos2); xx = verify_log(xx,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); if( (xx<0) || (xx>1) || (yy<0) || (yy>1) ) { // Throw away this strip : } if(first) { first = false; } else { vtxs->add(xprev,yprev,a_zz+zz); vtxs->add(xx,yy,a_zz+zz); vtxs->add_color(_color); vtxs->add_color(_color); } xprev = xx; yprev = yy; empty = false; } } } if(empty) { delete separator; } else { m_bins_sep.add(separator); } } void rep_contour_xy_filled(std::ostream& a_out,const style& a_style,painting_policy a_painting, const base_colormap& a_cmap,clist_contour& a_contour, const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z,float a_zz /*,const std::string& aID*/){ //a_out << "debug : rep_contour_xy_filled :" << std::endl; float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; float zmin = a_box_z.m_pos; float dz = a_box_z.m_width; //bool zlog = a_box_z.m_log; sg::separator* separator = new sg::separator; //separator->setString(aID); vec3f AB,BC,vcross; {// Draw background : sg::separator* sep = new sg::separator; separator->add(sep); float zz = a_zz - 0.01F; colorf _color; if(a_cmap.colorn()) { _color = a_cmap.color(0); } else { _color = a_style.color; } rgba* mat = new rgba(); mat->color = _color; sep->add(mat); float xx = xmin; float xe = xmin+dx; float yy = ymin; float ye = ymin+dy; xx = verify_log(xx,xmin,dx,xlog); xe = verify_log(xe,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); ye = verify_log(ye,ymin,dy,ylog); vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); vtxs->add(xx,yy,zz); vtxs->add(xe,yy,zz); vtxs->add(xe,ye,zz); vtxs->add(xx,ye,zz); sep->add(vtxs); } // End background. bool empty = true; for (unsigned int i=0;iadd(sep); //If zlog true, zz is already in log. float val = (float)a_contour.get_plane(i); float zz = val; zz = verify_log(zz,zmin,dz,false); if(zz>1) continue; if(zz<0) continue; std::vector< std::vector > contourVector; tools_lforcit(cline_strip*,*pStripList,pos) { cline_strip* pStrip = (*pos); if(pStrip->size() >2) { std::vector v; for (cline_strip::iterator pos2=pStrip->begin();pos2 != pStrip->end();pos2++) { unsigned int index=(*pos2); float xx = (float)a_contour.get_xi(index); float yy = (float)a_contour.get_yi(index); xx = verify_log(xx,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); v.push_back(vec3f(xx,yy,a_zz+zz)); } contourVector.push_back(std::move(v)); } } std::vector tris; tess_contour tessContour(a_out,tris); //we pass a ref to tris. tessContour.getFilledArea(contourVector); if(!tris.size()) continue; colorf _color; if(a_painting==painting_by_value) { a_cmap.get_color(val,_color); } else if(a_painting==painting_by_level) { int icol = a_cmap.colorn() ? (i % a_cmap.colorn()) :0; _color = a_cmap.color(icol); } else { _color = a_style.color; } atb_vertices* vtxs = new atb_vertices; //PAW_C/color.kumac. It needs back face. vtxs->mode = gl::triangles(); sep->add(vtxs); for(size_t itri=0;itri=0) { vtxs->add((float)tri.pointA[0],(float)tri.pointA[1],(float)tri.pointA[2]); vtxs->add((float)tri.pointB[0],(float)tri.pointB[1],(float)tri.pointB[2]); vtxs->add((float)tri.pointC[0],(float)tri.pointC[1],(float)tri.pointC[2]); } else { vtxs->add((float)tri.pointA[0],(float)tri.pointA[1],(float)tri.pointA[2]); vtxs->add((float)tri.pointC[0],(float)tri.pointC[1],(float)tri.pointC[2]); vtxs->add((float)tri.pointB[0],(float)tri.pointB[1],(float)tri.pointB[2]); } vtxs->add_color(_color); vtxs->add_color(_color); vtxs->add_color(_color); } empty = false; } if(empty) { delete separator; } else { m_bins_sep.add(separator); } } void rep_errors_plus_xy(std::ostream& /*a_out*/,const style& a_style,const std::vector& a_bins, const rep_box& a_box_x,const rep_box& a_box_y,const std::vector& a_bars,float aZ) { //a_out << "debug : rep_erros_plus_xy : begin :" << std::endl; separator* _sep = new separator(); //_sep->setString(aID); rgba* mat = new rgba(); mat->color = a_style.color; _sep->add(mat); draw_style* ds = new draw_style; ds->style.value(draw_lines); ds->line_pattern.value(a_style.line_pattern); ds->line_width.value(a_style.line_width); _sep->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::lines(); _sep->add(vtxs); float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; size_t xnbin = a_bins.size(); for(size_t index=0;index1) continue; if(xx<0) xx = 0; if(xe>1) xe = 1; //if(val<0) val = 0; //if(val>1) val = 1; float ex = (xe+xx)/2; //if( (ex >=0)&&(ex <=1) ) { //FIXME : have to clip float edx = 0.3F * (xe-xx); if((val>=0)&&(val<=1)) { vtxs->add(ex-edx,val,aZ); vtxs->add(ex+edx,val,aZ); } if(bar_min >1) { // do nothing } else if(bar_max <0) { // do nothing } else if(bar_min <0) { if(bar_max >1) { vtxs->add(ex,0,aZ); vtxs->add(ex,1,aZ); } else { vtxs->add(ex,0,aZ); vtxs->add(ex,bar_max,aZ); } } else if(bar_max >1) { vtxs->add(ex,bar_min,aZ); vtxs->add(ex,1,aZ); } else { vtxs->add(ex ,bar_min,aZ); vtxs->add(ex ,bar_max,aZ); } } if(vtxs->number()) { m_errors_sep.add(_sep); } else { delete _sep; } } void rep_errors_I_xy(std::ostream& /*a_out*/,const style& a_style,const std::vector& a_bins, const rep_box& a_box_x,const rep_box& a_box_y,const std::vector& a_bars,float aZ){ //a_out << "debug : rep_erros_I_xy : begin :" << std::endl; separator* _sep = new separator(); //_sep->setString(aID); rgba* mat = new rgba(); mat->color = a_style.color; _sep->add(mat); draw_style* ds = new draw_style; ds->style.value(draw_lines); ds->line_pattern.value(a_style.line_pattern); ds->line_width.value(a_style.line_width); _sep->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::lines(); _sep->add(vtxs); float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; size_t xnbin = a_bins.size(); for(size_t index=0;index1) continue; if(xx<0) xx = 0; if(xe>1) xe = 1; if(val<0) val = 0; if(val>1) val = 1; float ex = (xe+xx)/2; //if( (ex >=0)&&(ex <=1) ) { //FIXME : have to clip float edx = 0.3F * (xe-xx); if(bar_min >1) { // do nothing } else if(bar_max <0) { // do nothing } else if(bar_min <0) { if(bar_max >1) { vtxs->add(ex,0,aZ); vtxs->add(ex,1,aZ); } else { vtxs->add(ex,0,aZ); vtxs->add(ex,bar_max,aZ); vtxs->add(ex-edx,bar_max,aZ); vtxs->add(ex+edx,bar_max,aZ); } } else if(bar_max >1) { vtxs->add(ex-edx,bar_min,aZ); vtxs->add(ex+edx,bar_min,aZ); vtxs->add(ex,bar_min,aZ); vtxs->add(ex,1,aZ); } else { vtxs->add(ex-edx,bar_min,aZ); vtxs->add(ex+edx,bar_min,aZ); vtxs->add(ex ,bar_min,aZ); vtxs->add(ex ,bar_max,aZ); vtxs->add(ex-edx,bar_max,aZ); vtxs->add(ex+edx,bar_max,aZ); } } if(vtxs->number()) { m_errors_sep.add(_sep); } else { delete _sep; } } void rep_hatch1D_xy(const style& a_style, const std::vector& a_bins, const rep_box& a_box_x,const rep_box& a_box_y,float a_zz, bool a_bar_chart){ //printf("debug : tools::sg;:plotter::repHatch1D_xy : zz %g barchart %d sw %g\n",a_zz,aBarChart,a_style.stripWidth.getValue()); separator* _sep = new separator; rgba* mat = new rgba(); mat->color = a_style.color; _sep->add(mat); draw_style* ds = new draw_style; if(a_style.strip_width.value()==0) { ds->style = draw_lines; ds->line_pattern = line_solid; ds->line_width = a_style.line_width; } else { ds->style = draw_filled; //ds->cull_face = true; } _sep->add(ds); float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; bool empty = true; vec3f points[5]; size_t xnbin = a_bins.size(); for(size_t index=0;index1) continue; if(xe<0) continue; if(xx<0) xx = 0; if(xe>1) xe = 1; if(yy>1) continue; if(ye<0) continue; if(yy<0) yy = 0; if(ye>1) ye = 1; points[0].set_value(xx,yy,a_zz); points[1].set_value(xe,yy,a_zz); points[2].set_value(xe,ye,a_zz); points[3].set_value(xx,ye,a_zz); points[4].set_value(xx,yy,a_zz); //FIXME : have picking a hatch picks also the bin. hatcher _hatcher; _hatcher.set_offset_point(vec3f(0,0,a_zz)); _hatcher.set_angle(a_style.angle.value()); _hatcher.set_spacing(a_style.spacing.value()); if(!_hatcher.set_strip_width(a_style.strip_width.value())) {} bool res = _hatcher.check_polyline(points,4); if(res) res = _hatcher.compute_polyline(points,4); size_t numPoints = _hatcher.points().size(); size_t numVertices = _hatcher.vertices().size(); if((res) && numPoints && numVertices) { const std::vector& _points = _hatcher.points(); if(a_style.strip_width.value()==0) { size_t ipt = 0; tools_vforcit(unsigned int,_hatcher.vertices(),itv) { vertices* vtxs = new vertices; vtxs->mode = gl::line_strip(); for(size_t _index=0;_index<(*itv);_index++) { vtxs->add(_points[ipt]); ipt++; } _sep->add(vtxs); empty = false; } } else { size_t ipt = 0; tools_vforcit(unsigned int,_hatcher.vertices(),itv) { vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); for(size_t _index=0;_index<(*itv);_index++) { vtxs->add(_points[ipt]); ipt++; } _sep->add(vtxs); empty = false; } } } } if(empty) { delete _sep; } else { m_bins_sep.add(_sep); } } void rep_points2D_xy_lines(const style& a_style,const points2D& a_points, const rep_box& a_box_x,const rep_box& a_box_y,float a_zz){ //::printf("debug : rep_points2D_xy_lines\n"); float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; separator* _sep = new separator(); rgba* mat = new rgba(); mat->color = a_style.color; _sep->add(mat); draw_style* ds = new draw_style; ds->style.value(draw_lines); ds->line_pattern.value(a_style.line_pattern); ds->line_width.value(a_style.line_width); _sep->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::line_strip(); _sep->add(vtxs); bool empty = true; float x,y; unsigned int number = a_points.points(); for(unsigned int index=0;index1)||(y<0)||(y>1)) continue; vtxs->add(x,y,a_zz); empty = false; } if(empty) { delete _sep; } else { m_points_sep.add(_sep); } } void rep_points2D_xy_curve(std::ostream& a_out,const style& a_style,const points2D& a_points, const rep_box& a_box_x,const rep_box& a_box_y,float a_zz){ //::printf("debug : rep_points2D_xy_curve\n"); unsigned int number = a_points.points(); if(!number) return; double* xs = new double[number]; double* ys = new double[number]; float x,y; {for(unsigned int index=0;index points(nstp+1); for(unsigned int ibin=0;ibin<=nstp;ibin++) { float xx = xmn + ibin * step; double val = _spline.eval(xx); points[ibin].set_value(xx,float(val),a_zz); } vertices* vtxs = new vertices; std::vector& pts = vtxs->xyzs.values(); //npt*3 clip_polyline_2D(points,a_box_x,a_box_y,pts); if(pts.size()) { sg::separator* separator = new sg::separator; //separator->setString(aID); rgba* mat = new rgba(); mat->color = a_style.color; separator->add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = a_style.line_pattern; ds->line_width = a_style.line_width; separator->add(ds); vtxs->mode = gl::line_strip(); separator->add(vtxs); m_points_sep.add(separator); } else { delete vtxs; } } void rep_points2D_xy_points(std::ostream& a_out, const style& a_style,const points2D& a_points, const rep_box& a_box_x,const rep_box& a_box_y,float a_zz) { float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; separator* _sep = new separator(); rgba* mat = new rgba(); mat->color = a_style.color; _sep->add(mat); mf* _xyzs = 0; if(a_style.modeling==modeling_markers()) { markers* _marks = new markers; _marks->size = a_style.marker_size; _marks->style = a_style.marker_style; _xyzs = &(_marks->xyzs); _sep->add(_marks); } else if(a_style.modeling==modeling_points()) { draw_style* ds = new draw_style; ds->style = draw_points; ds->point_size = a_style.point_size; _sep->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::points(); _xyzs = &(vtxs->xyzs); _sep->add(vtxs); } else { a_out << "tools::sg::plotter::rep_points2D_xy_points :" << " bad modeling style " << tools::sout(a_style.modeling) << std::endl; delete _sep; return; } float x,y; // first round trip to get number of floats : size_t npts = 0; {unsigned int number = a_points.points(); for(unsigned int index=0;index1)||(y<0)||(y>1)) continue; npts += 3; }} _xyzs->values().resize(npts); size_t xyz_pos = 0; bool empty = true; {unsigned int number = a_points.points(); for(unsigned int index=0;index1)||(y<0)||(y>1)) continue; _xyzs->add_allocated(xyz_pos,x,y,a_zz); empty = false; }} if(empty) { delete _sep; } else { m_points_sep.add(_sep); } } void rep_points3D_xyz_points(std::ostream& a_out, const style& a_style,const points3D& a_points, const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z) { float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; float zmin = a_box_z.m_pos; float dz = a_box_z.m_width; bool zlog = a_box_z.m_log; separator* _sep = new separator(); rgba* mat = new rgba(); mat->color = a_style.color; _sep->add(mat); mf* _xyzs = 0; if(a_style.modeling==modeling_markers()) { markers* _marks = new markers; _marks->size = a_style.marker_size; _marks->style = a_style.marker_style; _xyzs = &(_marks->xyzs); _sep->add(_marks); } else if(a_style.modeling==modeling_points()) { draw_style* ds = new draw_style; ds->style = draw_points; ds->point_size = a_style.point_size; _sep->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::points(); _xyzs = &(vtxs->xyzs); _sep->add(vtxs); } else { a_out << "tools::sg::plotter::rep_points3D_xy_points :" << " bad modeling style " << tools::sout(a_style.modeling) << std::endl; delete _sep; return; } float x,y,z; // first round trip to get number of floats : size_t npts = 0; {unsigned int number = a_points.points(); for(unsigned int index=0;index1)||(y<0)||(y>1)||(z<0)||(z>1)) continue; npts += 3; }} _xyzs->values().resize(npts); size_t xyz_pos = 0; bool empty = true; {unsigned int number = a_points.points(); for(unsigned int index=0;index1)||(y<0)||(y>1)||(z<0)||(z>1)) continue; _xyzs->add_allocated(xyz_pos,x,y,z); empty = false; }} if(empty) { delete _sep; } else { m_points_sep.add(_sep); } } void rep_bins2D_xyz_box(const style& a_style,const base_colormap& a_cmap,const std::vector& a_bins, const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z,float a_bmin,float /*a_bmax*/){ float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; float zmin = a_box_z.m_pos; float dz = a_box_z.m_width; bool zlog = a_box_z.m_log; painting_policy painting = a_style.painting; separator* _sep = new separator(); bool empty = true; //float range = a_bmax - a_bmin; colorf clr; tools_vforcit(rep_bin2D,a_bins,it) { const rep_bin2D& rbin = *it; float xx = rbin.m_x_min; float xe = rbin.m_x_max; float yy = rbin.m_y_min; float ye = rbin.m_y_max; float val = rbin.m_val; float zz = a_bmin; float ze = val; xx = verify_log(xx ,xmin,dx ,xlog); xe = verify_log(xe ,xmin,dx ,xlog); yy = verify_log(yy ,ymin,dy ,ylog); ye = verify_log(ye ,ymin,dy ,ylog); zz = verify_log(zz ,zmin,dz ,zlog); ze = verify_log(ze ,zmin,dz ,zlog); // Clipping : if(xx>1) continue; if(xe<0) continue; if(xx<0) xx = 0; if(xe>1) xe = 1; if(yy>1) continue; if(ye<0) continue; if(yy<0) yy = 0; if(ye>1) ye = 1; if(zz>1) continue; if(ze<0) continue; if(zz<0) zz = 0; if(ze>1) ze = 1; if(yy>=ye) continue; if(xx>=xe) continue; if(zz>=ze) continue; separator* sep = new separator(); _sep->add(sep); if(painting==painting_by_value) { a_cmap.get_color(val,clr); } else if( (painting==painting_grey_scale) || (painting==painting_grey_scale_inverse) || (painting==painting_violet_to_red) ){ a_cmap.get_color(rbin.m_ratio,clr); } else { clr = a_style.color; } rgba* mat = new rgba(); mat->color = clr; sep->add(mat); /*{char s[128]; //::sprintf(s,"%d %d",rbin.fI,rbin.fJ); sep->setInfos(s); //::sprintf(s,"/0x%lx",(unsigned long)sep->getInfos()); std::string sid = aID; sid += std::string(s); sep->setString(sid);}*/ float sx = xe-xx; float sy = ye-yy; float sz = ze-zz; matrix* _tsf = new matrix; _tsf->set_translate(xx+sx/2,yy+sy/2,sz/2); sep->add(_tsf); cube* _cube = new cube; _cube->width = sx; _cube->height = sy; _cube->depth = sz; sep->add(_cube); empty = false; } if(empty) { delete _sep; } else { m_bins_sep.add(_sep); } } void rep_top_face2D_xyz(separator& a_sep,const style& a_style,const base_colormap& a_cmap, const std::vector& a_faces, const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z) { float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; float zmin = a_box_z.m_pos; float dz = a_box_z.m_width; bool zlog = a_box_z.m_log; bool empty = true; painting_policy painting = a_style.painting; separator* _sep = new separator(); //draw_style* ds = new draw_style; //ds->style = draw_filled; //ds->cull_face = true; //_sep->add(ds); atb_vertices* vtxs = new atb_vertices; vtxs->mode = gl::triangles(); vtxs->do_back = true; vtxs->epsilon = 1e-6f; _sep->add(vtxs); colorf clr; vec3f nm; size_t number = a_faces.size(); for(size_t index=0;index1) val1 = 1; if(val2<0) val2 = 0; if(val2>1) val2 = 1; if(val3<0) val3 = 0; if(val3>1) val3 = 1; if(val4<0) val4 = 0; if(val4>1) val4 = 1; if((xx>=0)&&(xx<=1) && (xe>=0)&&(xe<=1) && (yy>=0)&&(yy<=1) && (ye>=0)&&(ye<=1) ) { if(painting==painting_by_value) { float v = (zlog?take_log(val):val); a_cmap.get_color(v,clr); } else if( (painting==painting_grey_scale) || (painting==painting_grey_scale_inverse) || (painting==painting_violet_to_red) ){ a_cmap.get_color(a_faces[index].m_ratio,clr); } else { clr = a_style.color; } //if(a_style.area_style.getValue()==SoStyle::EDGED) { //OpenPAW. //} ////////////////////////////////////// ////////////////////////////////////// vtxs->add(xx,ye,val4); vtxs->add(xx,yy,val1); vtxs->add(xe,yy,val2); vtxs->add_color(clr); vtxs->add_color(clr); vtxs->add_color(clr); direction(xx,ye,val4, xx,yy,val1, xe,yy,val2,nm); nm.normalize(); vtxs->add_normal(nm[0],nm[1],nm[2]); vtxs->add_normal(nm[0],nm[1],nm[2]); vtxs->add_normal(nm[0],nm[1],nm[2]); ////////////////////////////////////// ////////////////////////////////////// vtxs->add(xe,yy,val2); vtxs->add(xe,ye,val3); vtxs->add(xx,ye,val4); vtxs->add_rgba(clr[0],clr[1],clr[2],clr[3]); vtxs->add_rgba(clr[0],clr[1],clr[2],clr[3]); vtxs->add_rgba(clr[0],clr[1],clr[2],clr[3]); direction(xe,yy,val2, xe,ye,val3, xx,ye,val4,nm); nm.normalize(); vtxs->add_normal(nm[0],nm[1],nm[2]); vtxs->add_normal(nm[0],nm[1],nm[2]); vtxs->add_normal(nm[0],nm[1],nm[2]); empty = false; } } if(empty) { delete _sep; } else { a_sep.add(_sep); } } void rep_top_face2D_xyz_line(const style& /*a_style*/,const std::vector& a_top_faces, const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z/*,const SbString& aID*/){ //::printf("debug : rep_top_face2D_xyz_line\n"); float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; float zmin = a_box_z.m_pos; float dz = a_box_z.m_width; bool zlog = a_box_z.m_log; sg::separator* separator = new sg::separator; bool empty = true; rgba* mat = new rgba(); mat->color = colorf_black(); separator->add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = line_solid; ds->line_width = 1; separator->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::lines(); separator->add(vtxs); float zepsilon = 0.02f; //for pawex9.kumac top-left and bottom-right. size_t number = a_top_faces.size(); for(size_t index=0;index1) val1 = 1; if(val2<0) val2 = 0; if(val2>1) val2 = 1; if(val3<0) val3 = 0; if(val3>1) val3 = 1; if(val4<0) val4 = 0; if(val4>1) val4 = 1; if((xx>=0)&&(xx<=1) && (xe>=0)&&(xe<=1) && (yy>=0)&&(yy<=1) && (ye>=0)&&(ye<=1) ) { vtxs->add(xx,ye,val4+zepsilon); vtxs->add(xx,yy,val1+zepsilon); vtxs->add(xx,yy,val1+zepsilon); vtxs->add(xe,yy,val2+zepsilon); vtxs->add(xe,yy,val2+zepsilon); vtxs->add(xe,ye,val3+zepsilon); vtxs->add(xe,ye,val3+zepsilon); vtxs->add(xx,ye,val4+zepsilon); empty = false; } } if(empty) { delete separator; } else { m_bins_sep.add(separator); } } void rep_top_face2D_xyz_by_level(const style& /*a_style*/,painting_policy /*a_painting*/,const base_colormap& a_cmap, const std::vector& a_top_faces, const rep_box& a_box_x,const rep_box& a_box_y,const rep_box& a_box_z, float a_bmin,float a_bmax/*,const SbString& aID*/){ //::printf("debug : rep_top_face2D_xyz_by_level\n"); size_t ncol = a_cmap.colorn(); if(!ncol) return; float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; float zmin = a_box_z.m_pos; float dz = a_box_z.m_width; bool zlog = a_box_z.m_log; float zz = a_bmin; zz = verify_log(zz,zmin,dz,zlog); float zmx = a_bmax; zmx = verify_log(zmx,zmin,dz,zlog); bool empty = true; sg::separator* separator = new sg::separator; //separator->setString(aID); atb_vertices* tris = new atb_vertices; tris->mode = gl::triangles(); tris->do_back = true; tris->epsilon = 1e-6f; separator->add(tris); colorf _color; vec3f _point; float d_z = (zmx-zz)/ncol; size_t number = a_top_faces.size(); for(size_t icol=0;icol1) val1 = 1; if(val2<0) val2 = 0; if(val2>1) val2 = 1; if(val3<0) val3 = 0; if(val3>1) val3 = 1; if(val4<0) val4 = 0; if(val4>1) val4 = 1; if((xx>=0)&&(xx<=1) && (xe>=0)&&(xe<=1) && (yy>=0)&&(yy<=1) && (ye>=0)&&(ye<=1) ) { ////////////////////////////////////// ////////////////////////////////////// {clip clipper; clipper.add(vec3f(xx,ye,val4)); clipper.add(vec3f(xx,yy,val1)); clipper.add(vec3f(xe,yy,val2)); //val[n] had been z normalized. float z1 = zz+d_z*icol; float z2 = z1+d_z; plane plane_z_bot(vec3f(0,0,1),vec3f(0,0,z1)); plane plane_z_top(vec3f(0,0,-1),vec3f(0,0,z2)); clipper.execute(plane_z_bot); clipper.execute(plane_z_top); const std::vector& result = clipper.result(); if(result.size()) { plane plane1(vec3f(xx,ye,val4),vec3f(xx,yy,val1),vec3f(xe,yy,val2)); if(result.size()==3) { tools_vforcit(vec3f,result,it) { tris->add(*it); tris->add_color(_color); tris->add_normal(plane1.normal()); } } else { atb_vertices* vtxs = new atb_vertices; //FIXME : ouch! optimize. vtxs->mode = gl::triangle_fan(); vtxs->do_back = true; vtxs->epsilon = 1e-6f; separator->add(vtxs); tools_vforcit(vec3f,result,it) { vtxs->add(*it); vtxs->add_color(_color); vtxs->add_normal(plane1.normal()); } } empty = false; //sep_empty = false; }} ////////////////////////////////////// ////////////////////////////////////// {clip clipper; clipper.add(vec3f(xe,yy,val2)); clipper.add(vec3f(xe,ye,val3)); clipper.add(vec3f(xx,ye,val4)); //val[n] had been z normalized. float z1 = zz+d_z*icol; float z2 = z1+d_z; plane plane_z_bot(vec3f(0,0,1),vec3f(0,0,z1)); plane plane_z_top(vec3f(0,0,-1),vec3f(0,0,z2)); clipper.execute(plane_z_bot); clipper.execute(plane_z_top); const std::vector& result = clipper.result(); if(result.size()) { plane plane2(vec3f(xe,yy,val2),vec3f(xe,ye,val3),vec3f(xx,ye,val4)); if(result.size()==3) { tools_vforcit(vec3f,result,it) { tris->add(*it); tris->add_color(_color); tris->add_normal(plane2.normal()); } } else { atb_vertices* vtxs = new atb_vertices; //FIXME : ouch! optimize. vtxs->mode = gl::triangle_fan(); vtxs->do_back = true; vtxs->epsilon = 1e-6f; separator->add(vtxs); tools_vforcit(vec3f,result,it) { vtxs->add(*it); vtxs->add_color(_color); vtxs->add_normal(plane2.normal()); } } empty = false; //sep_empty = false; }} } } //index faces //if(sep_empty) { // delete sep; //} else { // separator->add(sep); //} } //icol if(empty) { delete separator; } else { m_bins_sep.add(separator); } } // for OpenPAW /GRAPHICS/PRIMITIVES/TEXT // for OpenPAW /GRAPHICS/PRIMITIVES/ITX void update_primitive_text(const plottable_text& a_obj){ if(a_obj.m_TEXT.empty()) return; float z = xy_depth.value()*1.1F; vec3f pos; axis_2_data_frame(vec3f(a_obj.m_X,a_obj.m_Y,z),pos); //FIXME return FALSE xx_2_yy(pos,pos); separator* sep = new separator; rgba* mat = new rgba(); mat->color = a_obj.m_TXCI; sep->add(mat); matrix* _tsf = new matrix; _tsf->set_translate(pos); _tsf->mul_rotate(0,0,1,a_obj.m_ANGLE*fpi()/180.0f); _tsf->mul_scale(a_obj.m_SCALE,a_obj.m_SCALE,1); sep->add(_tsf); //SIZE is in page coordinate YSIZ. //float YSIZ = height.value(); //if(YSIZ<=0) YSIZ = 1; //::printf("debug : tools::sg::plotter::update_primitive_text : %s : X %g Y %g : SCALE %g SIZE %g : pos %g %g %g\n", // a_obj.m_TEXT.c_str(),a_obj.m_X,a_obj.m_Y,a_obj.m_SCALE,a_obj.m_SIZE, // pos[0],pos[1],pos[2]); if(a_obj.m_text_mode==plottable_text::text_enforce_width) { // not tested yet. vec3f pos2; 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. xx_2_yy(pos2,pos2); float _width = pos2.x()-pos.x(); text* _text = new text(m_ttf); _text->enforce_front_width = true; //it will set _text->width, height. _text->front_width = _width; _text->back_visible = false; _text->encoding = encoding_PAW(); _text->strings.add(a_obj.m_TEXT); _text->line_width = a_obj.m_line_width; _text->font = a_obj.m_FONT; _text->font_modeling = a_obj.m_font_modeling; if(a_obj.m_HJUST=='R') { _text->hjust = right; } else if(a_obj.m_HJUST=='C') { _text->hjust = center; } else { _text->hjust = left; } if(a_obj.m_VJUST=='T') { _text->vjust = top; } else if(a_obj.m_VJUST=='M') { _text->vjust = middle; } else { _text->vjust = bottom; } sep->add(_text); } else if(a_obj.m_text_mode==plottable_text::text_enforce_height) { // for EsbRootView neard, fard 2D plot. vec3f pos2; 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. xx_2_yy(pos2,pos2); float _height = pos2.y()-pos.y(); text* _text = new text(m_ttf); _text->enforce_front_height = true; //it will set _text->width, height. _text->front_height = _height; _text->back_visible = false; //if true, we should adapt back_area::width, height to inside text size. _text->encoding = encoding_PAW(); _text->strings.add(a_obj.m_TEXT); _text->line_width = a_obj.m_line_width; _text->font = a_obj.m_FONT; _text->font_modeling = a_obj.m_font_modeling; if(a_obj.m_HJUST=='R') { _text->hjust = right; } else if(a_obj.m_HJUST=='C') { _text->hjust = center; } else { _text->hjust = left; } if(a_obj.m_VJUST=='T') { _text->vjust = top; } else if(a_obj.m_VJUST=='M') { _text->vjust = middle; } else { _text->vjust = bottom; } sep->add(_text); } else { //text_as_it (for gopaw/pagpri.cpp). _tsf->mul_scale(a_obj.m_SIZE,a_obj.m_SIZE,1); if(a_obj.m_FONT==font_hershey()) { //::printf("debug : tools::sg::plotter::update_primitive_text : hershey\n"); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = line_solid; ds->line_width = a_obj.m_line_width; //ds->line_pattern = m_title_style.line_pattern; //ds->line_width = m_title_style.line_width; sep->add(ds); text_hershey* text = new text_hershey; text->encoding = encoding_PAW(); text->strings.add(a_obj.m_TEXT); if(a_obj.m_HJUST=='R') { text->hjust = right; } else if(a_obj.m_HJUST=='C') { text->hjust = center; } else { text->hjust = left; } if(a_obj.m_VJUST=='T') { text->vjust = top; } else if(a_obj.m_VJUST=='M') { text->vjust = middle; } else { text->vjust = bottom; } sep->add(text); } else { //::printf("debug : tools::sg::plotter::update_primitive_text : freetype\n"); base_freetype* text = base_freetype::create(m_ttf); text->font = a_obj.m_FONT; if(a_obj.m_HJUST=='R') { text->hjust = right; } else if(a_obj.m_HJUST=='C') { text->hjust = center; } else { text->hjust = left; } if(a_obj.m_VJUST=='T') { text->vjust = top; } else if(a_obj.m_VJUST=='M') { text->vjust = middle; } else { text->vjust = bottom; } text->modeling = a_obj.m_font_modeling; //text->encoding = encoding_PAW() //text->smooting = a_obj.m_SMOOTHING; //text->hinting = a_obj.m_HINTING; text->strings.add(a_obj.m_TEXT); //text->hjust.value(a_hjust); //text->vjust.value(a_vjust); sep->add(text); } } //text_mode. m_primitives_sep.add(sep); } // for OpenPAW /GRAPHICS/PRIMITIVES/BOX void PAW_hatch(int aHTYP,hatching_policy& a_policy,float& a_spacing,float& a_angle_right,float& a_angle_left) { // PAW hatching encoding (paw.pdf 1.14(1992) p 174) : a_policy = hatching_none; a_spacing = 0; a_angle_right = 0; a_angle_left = 0; int code = aHTYP; if(code==0) return; // From PAW FAQ web page. // special code from code [1,25] if(code==1) { a_policy = hatching_left_and_right; a_spacing = 0.04F; a_angle_right = 3.0F*fpi()/4.0F; a_angle_left = fpi()/4.0F; return; } else if(code==2) { a_policy = hatching_left_and_right; a_spacing = 0.08F; a_angle_right = 3.0F*fpi()/4.0F; a_angle_left = fpi()/4.0F; return; } else if(code==3) { a_policy = hatching_left_and_right; a_spacing = 1.6f*0.07F; //cooking a_angle_right = 3.0F*fpi()/4.0F; a_angle_left = fpi()/4.0F; return; } else if(code==4) { code = 354; } else if(code==5) { code = 345; } else if(code==6) { code = 359; } else if(code==7) { code = 350; } else if(code<=25) { //FIXME : seems to be done with patterns. a_policy = hatching_none; return; } else if(code<=99) { //FIXME a_policy = hatching_none; return; } //code >=100 // code = ijk int i = code / 100; int j = (code - i * 100)/10; int k = code - i * 100 - j * 10; // j-hatching on rightHatchStyle : // k-hatching on leftHatchStyle : if((j==5)&&(k==5)) a_policy = hatching_none; else if((j!=5)&&(k==5)) a_policy = hatching_right; else if((j==5)&&(k!=5)) a_policy = hatching_left; else if((j!=5)&&(k!=5)) a_policy = hatching_left_and_right; unsigned int NY = 1; a_spacing = float(NY) * float(i) * 0.07F; //cooking if(j!=5) { float angle = float(j==4?45:j*10); angle = 180.0F - angle; angle *= fpi() / 180.0F; a_angle_right = angle; } if(k!=5) { float angle = float(k==4?45:k*10); angle *= fpi() / 180.0F; a_angle_left = angle; } } void rep_box_hatch(separator& a_parent,float a_spacing,float a_angle,float a_strip_width, float xx,float yy,float xe,float ye,float a_zz){ //printf("debug : SoPlotter::repHatch1D_xy : zz %g\n",a_zz); sg::separator* separator = new sg::separator; bool empty = true; vec3f points[5]; points[0].set_value(xx,yy,a_zz); points[1].set_value(xe,yy,a_zz); points[2].set_value(xe,ye,a_zz); points[3].set_value(xx,ye,a_zz); points[4].set_value(xx,yy,a_zz); //We can have multiple hatching for a bins ; have a separator : hatcher _hatcher; _hatcher.set_offset_point(vec3f(0,0,a_zz)); _hatcher.set_angle(a_angle); _hatcher.set_spacing(a_spacing); if(!_hatcher.set_strip_width(a_strip_width)) {} bool res = _hatcher.check_polyline(points,4); if(res) res = _hatcher.compute_polyline(points,4); size_t numPoints = _hatcher.points().size(); size_t numVertices = _hatcher.vertices().size(); if((res) && numPoints && numVertices) { const std::vector& _points = _hatcher.points(); if(a_strip_width==0) { size_t ipt = 0; tools_vforcit(unsigned int,_hatcher.vertices(),itv) { vertices* vtxs = new vertices; vtxs->mode = gl::line_strip(); for(size_t index=0;index<(*itv);index++) { vtxs->add(_points[ipt]); ipt++; } separator->add(vtxs); empty = false; } } else { size_t ipt = 0; tools_vforcit(unsigned int,_hatcher.vertices(),itv) { vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); for(size_t index=0;index<(*itv);index++) { vtxs->add(_points[ipt]); ipt++; } separator->add(vtxs); empty = false; } } empty = false; } if(empty) { delete separator; } else { a_parent.add(separator); } } void update_primitive_box(std::ostream& a_out,const plottable_box& a_obj){ float z = xy_depth.value()*1.1F; vec3f pos1; axis_2_data_frame(vec3f(a_obj.m_X1,a_obj.m_Y1,z),pos1); xx_2_yy(pos1,pos1); vec3f pos2; axis_2_data_frame(vec3f(a_obj.m_X2,a_obj.m_Y2,z),pos2); xx_2_yy(pos2,pos2); z = pos1[2]; // ::printf("debug : tools::sg::plotter::update_primitive_box : FAIS %d : %g %g %g : %g %g %g\n",a_obj.m_FAIS, // pos1.x(),pos1.y(),pos1.z(),pos2.x(),pos2.y(),pos2.z()); if(a_obj.m_FAIS==plottable_box::HOLLOW) { separator* sep = new separator; rgba* mat = new rgba(); mat->color = a_obj.m_PLCI; sep->add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = line_solid; ds->line_width = a_obj.m_LWID; sep->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::line_strip(); sep->add(vtxs); vtxs->add(pos1[0],pos1[1],z); vtxs->add(pos2[0],pos1[1],z); vtxs->add(pos2[0],pos2[1],z); vtxs->add(pos1[0],pos2[1],z); vtxs->add(pos1[0],pos1[1],z); m_primitives_sep.add(sep); } else if(a_obj.m_FAIS==plottable_box::SOLID) { separator* sep = new separator; rgba* mat = new rgba(); mat->color = a_obj.m_FACI; sep->add(mat); draw_style* ds = new draw_style; ds->style = draw_filled; sep->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); sep->add(vtxs); vtxs->add(pos1[0],pos1[1],z); vtxs->add(pos2[0],pos1[1],z); vtxs->add(pos2[0],pos2[1],z); vtxs->add(pos1[0],pos2[1],z); m_primitives_sep.add(sep); } else if(a_obj.m_FAIS==plottable_box::HATCHED) { {separator* sep = new separator; rgba* mat = new rgba(); mat->color = a_obj.m_FACI; sep->add(mat); hatching_policy hatching; float spacing; float angle_right; float angle_left; PAW_hatch(a_obj.m_FASI,hatching,spacing,angle_right,angle_left); float stripWidth = 0; if((hatching==hatching_right)||((hatching==hatching_left_and_right))) { rep_box_hatch(*sep,spacing,angle_right,stripWidth,pos1[0],pos1[1],pos2[0],pos2[1],z); } if((hatching==hatching_left)||((hatching==hatching_left_and_right))) { rep_box_hatch(*sep,spacing,angle_left,stripWidth,pos1[0],pos1[1],pos2[0],pos2[1],z); } if(hatching==hatching_none) { draw_style* ds = new draw_style; ds->style = draw_filled; sep->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); sep->add(vtxs); vtxs->add(pos1[0],pos1[1],z); vtxs->add(pos2[0],pos1[1],z); vtxs->add(pos2[0],pos2[1],z); vtxs->add(pos1[0],pos2[1],z); } m_primitives_sep.add(sep);} if(a_obj.m_BORD) { separator* sep = new separator; rgba* mat = new rgba(); mat->color = a_obj.m_PLCI; sep->add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = line_solid; ds->line_width = 1; sep->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::line_strip(); sep->add(vtxs); z *= 1.01F; vtxs->add(pos1[0],pos1[1],z); vtxs->add(pos2[0],pos1[1],z); vtxs->add(pos2[0],pos2[1],z); vtxs->add(pos1[0],pos2[1],z); vtxs->add(pos1[0],pos1[1],z); m_primitives_sep.add(sep); } } else if(a_obj.m_FAIS==plottable_box::PATTERN) { a_out << "tools::sg::plotter::update_plottable_box FAIS PATTERN not yet handled." << std::endl; } } void update_primitive_ellipse(std::ostream& a_out,const plottable_ellipse& a_obj){ float z = xy_depth.value()*1.1F; vec3f pos; axis_2_data_frame(vec3f(a_obj.m_X,a_obj.m_Y,z),pos); xx_2_yy(pos,pos); vec3f pos2; axis_2_data_frame(vec3f(a_obj.m_X+a_obj.m_R1,a_obj.m_Y+a_obj.m_R2,z),pos2); xx_2_yy(pos2,pos2); float rx = pos2[0]-pos[0]; float ry = pos2[1]-pos[1]; z = pos[2]; //::printf("debug : tools::sg::plotter::update_primitive_ellipse : FAIS %d : %g %g %g : %g %g\n",a_obj.m_FAIS, // pos.x(),pos.y(),pos.z(),rx,ry); if(a_obj.m_FAIS==plottable_ellipse::HOLLOW) { separator* sep = new separator; matrix* _tsf = new matrix; _tsf->set_translate(pos); sep->add(_tsf); rgba* mat = new rgba(); mat->color = a_obj.m_PLCI; sep->add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = line_solid; ds->line_width = a_obj.m_LWID; sep->add(ds); ellipse* _ellipse = new ellipse; _ellipse->rx = rx; _ellipse->ry = ry; sep->add(_ellipse); m_primitives_sep.add(sep); /* } else if(a_obj.m_FAIS==plottable_ellipse::SOLID) { separator* sep = new separator; rgba* mat = new rgba(); mat->color = a_obj.m_FACI; sep->add(mat); draw_style* ds = new draw_style; ds->style = draw_filled; sep->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); sep->add(vtxs); vtxs->add(pos1[0],pos1[1],z); vtxs->add(pos2[0],pos1[1],z); vtxs->add(pos2[0],pos2[1],z); vtxs->add(pos1[0],pos2[1],z); m_primitives_sep.add(sep); } else if(a_obj.m_FAIS==plottable_ellipse::HATCHED) { {separator* sep = new separator; rgba* mat = new rgba(); mat->color = a_obj.m_FACI; sep->add(mat); hatching_policy hatching; float spacing; float angle_right; float angle_left; PAW_hatch(a_obj.m_FASI,hatching,spacing,angle_right,angle_left); float stripWidth = 0; if((hatching==hatching_right)||((hatching==hatching_left_and_right))) { rep_box_hatch(*sep,spacing,angle_right,stripWidth,pos1[0],pos1[1],pos2[0],pos2[1],z); } if((hatching==hatching_left)||((hatching==hatching_left_and_right))) { rep_box_hatch(*sep,spacing,angle_left,stripWidth,pos1[0],pos1[1],pos2[0],pos2[1],z); } if(hatching==hatching_none) { draw_style* ds = new draw_style; ds->style = draw_filled; sep->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::triangle_fan(); sep->add(vtxs); vtxs->add(pos1[0],pos1[1],z); vtxs->add(pos2[0],pos1[1],z); vtxs->add(pos2[0],pos2[1],z); vtxs->add(pos1[0],pos2[1],z); } m_primitives_sep.add(sep);} if(a_obj.m_BORD) { separator* sep = new separator; rgba* mat = new rgba(); mat->color = a_obj.m_PLCI; sep->add(mat); draw_style* ds = new draw_style; ds->style = draw_lines; ds->line_pattern = line_solid; ds->line_width = 1; sep->add(ds); vertices* vtxs = new vertices; vtxs->mode = gl::line_strip(); sep->add(vtxs); z *= 1.01F; vtxs->add(pos1[0],pos1[1],z); vtxs->add(pos2[0],pos1[1],z); vtxs->add(pos2[0],pos2[1],z); vtxs->add(pos1[0],pos2[1],z); vtxs->add(pos1[0],pos1[1],z); m_primitives_sep.add(sep); } } else if(a_obj.m_FAIS==plottable_ellipse::PATTERN) { a_out << "tools::sg::plotter::update_plottable_box FAIS PATTERN not yet handled." << std::endl; */ } else { a_out << "tools::sg::plotter::update_plottable_box FAIS " << a_obj.m_FAIS << " not yet handled." << std::endl; } } void update_primitive_img(std::ostream& /*a_out*/,const plottable_img& a_obj){ float z = xy_depth.value()*1.1F; vec3f pos; axis_2_data_frame(vec3f(a_obj.m_X,a_obj.m_Y,z),pos); xx_2_yy(pos,pos); //pos = center of image in axes coordinates. z = pos[2]; vec3f top; axis_2_data_frame(vec3f(0,a_obj.m_Y+a_obj.m_HEIGHT*0.5f,0),top); xx_2_yy(top,top); //top = (o,y-top) of image in axes coordinates. float scale = 2.0f*(top[1]-pos[1]); //float scale = a_obj.m_HEIGHT; //m_HEIGHT is then in page coordinate YSIZ. const img& img = a_obj.m_img; //::printf("debug : tools::sg::plotter::update_primitive_img : %d %d %d : %g %g %g : %g : %g %g\n", // img.width(),img.height(),img.bpp(), // pos.x(),pos.y(),pos.z(),a_obj.m_HEIGHT,a_obj.m_THETA,a_obj.m_PHI); separator* sep = new separator; rgba* mat = new rgba(); mat->color = colorf_white(); sep->add(mat); normal* nm = new normal; sep->add(nm); matrix* _tsf = new matrix; _tsf->set_translate(pos); _tsf->mul_rotate(0,1,0,a_obj.m_THETA*fpi()/180.0f); _tsf->mul_rotate(0,0,1,a_obj.m_PHI*fpi()/180.0f); _tsf->mul_scale(scale,scale,1); sep->add(_tsf); tex_rect* _img = new tex_rect(); _img->img = img; sep->add(_img); m_primitives_sep.add(sep); } protected: //etc // background is at z = 0. // last z items are text in infos, legend boxes that should be at xy_depth(). float _zoffset() const { // first data plane is at _zoffset. // last one at m_plottables.size()*_zoffset = xy_depth.value()-_zoffset(). return xy_depth.value()/(float(m_plottables.size())+1.0f); } float _zaxis() const {return _zoffset();} float _zgrid() const {return xy_depth.value()-_zoffset()*0.5f;} float _ztext() const {return 0.01f;} //if text back is visible else 0. (sf zfront ?) float _zscale_text() const {return _zoffset()*0.4f/_ztext();} //title and infos boxes thickness. float _zinfos() const {return xy_depth.value()-_zoffset()*0.4f;} //in front _zgrid float _zhatch() const {return _zoffset()*0.25f;} float _zerrors() const {return _zoffset()*0.5f;} //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);} static float take_log(float a_x){ if(a_x<=0) { return -FLT_MAX; } else { return flog10(a_x); } } static float verify_log(float a_val,float a_min,float a_dx,bool a_log){ if(a_log) { if(a_val>0.0F) { return (flog10(a_val) - a_min)/a_dx; } else { // Return a negative large number : //return -FLT_MAX; return -100; } } else { // Simple protection against value that could exceed a float : if(a_val>(a_min+100.0F * a_dx)) return 100; if(a_val<(a_min-100.0F * a_dx)) return -100; // Rescale : return (a_val - a_min)/a_dx; } } static float verify_log_inv(float a_val,float a_min,float a_dx,bool a_log){ if(a_log) { return fpow(10,a_val*a_dx+a_min); } else { return a_val*a_dx+a_min; } } style* merge_bins_style(unsigned int a_index,plottable&) { style& _style = bins_style(a_index); //uuu merge with a_p.infos(). return new style(_style); } style* merge_left_hatch_style(unsigned int a_index,plottable&) { style& _style = left_hatch_style(a_index); //uuu merge with a_p.infos(). return new style(_style); } style* merge_right_hatch_style(unsigned int a_index,plottable&) { style& _style = right_hatch_style(a_index); //uuu merge with a_p.infos(). return new style(_style); } style* merge_errors_style(unsigned int a_index,plottable&) { style& _style = errors_style(a_index); //uuu merge with a_p.infos(). return new style(_style); } style* merge_func_style(unsigned int a_index,plottable&) { style& _style = func_style(a_index); //uuu merge with a_p.infos(). return new style(_style); } style* merge_points_style(unsigned int a_index,plottable&) { style& _style = points_style(a_index); //uuu merge with a_p.infos(). return new style(_style); } /* text_style* merge_legend_style(unsigned int a_index,plottable& a_p) { if(a_index>=m_legend_style.size()) return new text_style(); return new text_style(m_legend_style[a_index]); //uuu merge with a_p.infos(). } */ shape_type get_shape() const { if(!shape_automated) return shape.value(); // Guess XY or XYZ shape : /*if(f_binsList.size()) { // major bins compells shape type. if(f_binsList[0]->getDimension()==1) { return XY; } else if(f_binsList[0]->getDimension()==2) { return XY; //lego is not the default. } else { return XYZ; } } else if(f_pointsList.size()) { // major points compells shape type. if(f_pointsList[0]->getDimension()==1) { //? return XY; } else if(f_pointsList[0]->getDimension()==2) { return XY; } else { return XYZ; } } else if(f_functionList.size()) { // major function compell shape type. if(f_functionList[0]->getDimension()==1) { return XY; } else { return XYZ; } } else*/ { return xy; //Default. } } void clear_plottables() { //unsigned int objn = m_plottables.size(); {std::vector::iterator it; for(it=m_plottables.begin();it!=m_plottables.end();++it) delete *it; m_plottables.clear();} /* if(objn) { // If a title (logScale) had been given on some axis, // it is probably no more pertinent for further data. if(xAxisEnforced.value()==false) { m_x_axis.title.setValue(""); xAxisLogScale.setValue(false); } if(yAxisEnforced.value()==false) { m_y_axis.title.setValue(""); yAxisLogScale.setValue(false); } if(zAxisEnforced.value()==false) { m_z_axis.title.setValue(""); zAxisLogScale.setValue(false); } } */ touch(); } void clear_primitives() { {std::vector::iterator it; for(it=m_primitives.begin();it!=m_primitives.end();++it) delete *it; m_primitives.clear();} touch(); } void clear_todels() {m_todel_group.clear();} bool first_bins(bins1D*& a_1,bins2D*& a_2) const { tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(bins1D* b1 = safe_cast(*object)) { a_1 = b1; a_2 = 0; return true; } else if(bins2D* b2 = safe_cast(*object)) { a_1 = 0; a_2 = b2; return true; } } a_1 = 0; a_2 = 0; return false; } bool first_func(func1D*& a_1,func2D*& a_2) const { tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(func1D* f1 = safe_cast(*object)) { a_1 = f1; a_2 = 0; return true; } else if(func2D* f2 = safe_cast(*object)) { a_1 = 0; a_2 = f2; return true; } } a_1 = 0; a_2 = 0; return false; } bool first_points(points2D*& a_2,points3D*& a_3) const { tools_vforcit(plottable*,m_plottables,it) { plottable* object = *it; if(!object) continue; if(points2D* p2 = safe_cast(*object)) { a_2 = p2; a_3 = 0; return true; } else if(points3D* p3 = safe_cast(*object)) { a_2 = 0; a_3 = p3; return true; } } a_2 = 0; a_3 = 0; return false; } void clear_sg() { m_bins_sep.clear(); m_errors_sep.clear(); m_func_sep.clear(); m_points_sep.clear(); } void DUMP_UPDATE_WHAT(std::ostream&,const std::string&) {} /* void DUMP_UPDATE_WHAT(std::ostream& a_out,const std::string& a_msg) { a_out << "tools::sg::plotter :" << " " << a_msg << std::endl; } */ static void add_pt(std::vector& a_pts,float a_x,float a_y,float a_z){ a_pts.push_back(a_x); a_pts.push_back(a_y); a_pts.push_back(a_z); } static void clip_points_2D(const std::vector& a_points, const rep_box& a_box_x,const rep_box& a_box_y,std::vector& a_pts) { float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; a_pts.clear(); float xx,yy,zz; tools_vforcit(vec3f,a_points,it) { const vec3f& _point = *it; xx = _point[0]; yy = _point[1]; zz = _point[2]; xx = verify_log(xx,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); if((xx>=0)&&(xx<=1)&&(yy>=0)&&(yy<=1)) add_pt(a_pts,xx,yy,zz); } } static void clip_polyline_2D(const std::vector& a_points, const rep_box& a_box_x,const rep_box& a_box_y,std::vector& a_pts) { // Clip line in a_box_x, a_box_y. //NOTE : it is not a general algorithm. // It is assumed that a_points are ordered with increasing x. // And the algorithm clips against up and bottom BoxY lines. // (Use clip for a more general algorithm ?) float xmin = a_box_x.m_pos; float dx = a_box_x.m_width; bool xlog = a_box_x.m_log; float ymin = a_box_y.m_pos; float dy = a_box_y.m_width; bool ylog = a_box_y.m_log; a_pts.clear(); float xprev = 0; float yprev = 0; {unsigned int index = 0; std::vector::const_iterator it; for(it=a_points.begin();it!=a_points.end();++it,index++) { const vec3f& _point = *it; float xx = _point[0]; float yy = _point[1]; float zz = _point[2]; //add_pt(a_pts,xx,yy,zz);continue; //debug xx = verify_log(xx,xmin,dx,xlog); yy = verify_log(yy,ymin,dy,ylog); if((xx>=0)&&(xx<=1) ) { if(yy>1) { if(index==0) { add_pt(a_pts,xx,1,zz); } else { if(yprev>1) { add_pt(a_pts,xx,1,zz); } else if(yprev<0) { float a = (yy - yprev)/(xx - xprev); float b = yy - a * xx; add_pt(a_pts,-b/a,0,zz); add_pt(a_pts,(1 - b)/a,1,zz); add_pt(a_pts,xx,1,zz); } else { float a = (yy - yprev)/(xx - xprev); float b = yy - a * xx; add_pt(a_pts,(1 - b)/a,1,zz); add_pt(a_pts,xx,1,zz); } } } else if (yy < 0) { if(index==0) { add_pt(a_pts,xx,0,zz); } else { if(yprev<0) { add_pt(a_pts,xx,0,zz); } else if(yprev>1) { float a = (yy - yprev)/(xx - xprev); float b = yy - a * xx; add_pt(a_pts,(1 - b)/a,1,zz); add_pt(a_pts,-b/a,0,zz); add_pt(a_pts,xx,0,zz); } else { float a = (yy - yprev)/(xx - xprev); float b = yy - a * xx; add_pt(a_pts,-b/a,0,zz); add_pt(a_pts,xx,0,zz); } } } else { if(index==0) { add_pt(a_pts,xx,yy,zz); } else if( (yprev>1) || (yprev<0) ) { // interpolate : float a = (yy - yprev)/(xx - xprev); float b = yy - a * xx; if(yprev>1) { add_pt(a_pts,(1 - b)/a,1,zz); } else { add_pt(a_pts,-b/a,0,zz); } add_pt(a_pts,xx,yy,zz); } else { add_pt(a_pts,xx,yy,zz); } } } xprev = xx; yprev = yy; }} } bool sto(const std::string& a_s,vec2f& a_v) { std::vector ws; words(a_s," ",false,ws); if(ws.size()!=2) return false; float x = 0; if(!to(ws[0],x)) return false; float y = 0; if(!to(ws[1],x)) return false; a_v.set_value(x,y); return true; } bool sto(const std::string& a_s,unit_type& a_v) { if(a_s=="percent") {a_v = unit_percent;return true;} else if(a_s=="axis") {a_v = unit_axis;return true;} return false; } void clear_cmaps() { {std::vector::iterator it; for(it=m_bins_cmaps.begin();it!=m_bins_cmaps.end();++it) delete *it; m_bins_cmaps.clear();} {std::vector::iterator it; for(it=m_points_cmaps.begin();it!=m_points_cmaps.end();++it) delete *it; m_points_cmaps.clear();} {std::vector::iterator it; for(it=m_func_cmaps.begin();it!=m_func_cmaps.end();++it) delete *it; m_func_cmaps.clear();} } void bar_chart(float a_bar_offset,float a_bar_width, float& a_beg,float& a_end){ float xe = (a_end - a_beg)*a_bar_offset; float xw = (a_end - a_beg)*a_bar_width; a_end = a_beg + xe + xw; a_beg = a_beg + xe; } protected: const base_freetype& m_ttf; protected: //fields for skeleton. group m_group; separator m_background_sep; separator m_cmap_sep; matrix m_cmap_matrix; separator m_cmap_cells_sep; matrix m_cmap_axis_matrix; sg::axis m_cmap_axis; separator m_infos_title_sep; separator m_infos_sep; separator m_legend_sep; separator m_title_box_sep; matrix m_tsf; matrix m_layout; separator m_title_sep; separator m_x_axis_sep; matrix m_x_axis_matrix; sg::axis m_x_axis; separator m_y_axis_sep; matrix m_y_axis_matrix; sg::axis m_y_axis; separator m_z_axis_sep; matrix m_z_axis_matrix; sg::axis m_z_axis; separator m_grid_sep; separator m_data_sep; torche m_data_light; matrix m_data_matrix; separator m_bins_sep; separator m_errors_sep; separator m_func_sep; separator m_points_sep; separator m_inner_frame_sep; separator m_primitives_sep; separator m_etc_sep; protected: //fields shape_type m_shape; data_axis m_x_axis_data; data_axis m_y_axis_data; data_axis m_z_axis_data; std::vector m_plottables; //it has ownership. std::vector