Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef tools_sg_vertices 4 #ifndef tools_sg_vertices 5 #define tools_sg_vertices 5 #define tools_sg_vertices 6 6 7 #include "node" 7 #include "node" 8 #include "gstos" 8 #include "gstos" 9 9 10 #include "sf" 10 #include "sf" 11 #include "mf" 11 #include "mf" 12 #include "render_action" 12 #include "render_action" 13 #include "pick_action" 13 #include "pick_action" 14 #include "bbox_action" 14 #include "bbox_action" 15 #include "visible_action" 15 #include "visible_action" 16 16 17 #include "../vmanip" 17 #include "../vmanip" 18 18 19 namespace tools { 19 namespace tools { 20 namespace sg { 20 namespace sg { 21 21 22 class vertices : public node, public gstos { 22 class vertices : public node, public gstos { 23 TOOLS_NODE(vertices,tools::sg::vertices,node 23 TOOLS_NODE(vertices,tools::sg::vertices,node) 24 typedef gstos parent_gstos; 24 typedef gstos parent_gstos; 25 public: 25 public: 26 sf<gl::mode_t> mode; 26 sf<gl::mode_t> mode; 27 mf<float> xyzs; 27 mf<float> xyzs; 28 public: 28 public: 29 virtual const desc_fields& node_desc_fields( 29 virtual const desc_fields& node_desc_fields() const { 30 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::ver 30 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::vertices) 31 static const desc_fields s_v(parent::node_ 31 static const desc_fields s_v(parent::node_desc_fields(),2, //WARNING : take care of count. 32 TOOLS_ARG_FIELD_DESC(mode), 32 TOOLS_ARG_FIELD_DESC(mode), 33 TOOLS_ARG_FIELD_DESC(xyzs) 33 TOOLS_ARG_FIELD_DESC(xyzs) 34 ); 34 ); 35 return s_v; 35 return s_v; 36 } 36 } 37 private: 37 private: 38 void add_fields(){ 38 void add_fields(){ 39 add_field(&mode); 39 add_field(&mode); 40 add_field(&xyzs); 40 add_field(&xyzs); 41 } 41 } 42 protected: //gstos 42 protected: //gstos 43 virtual unsigned int create_gsto(std::ostrea 43 virtual unsigned int create_gsto(std::ostream&,sg::render_manager& a_mgr) { 44 //unsigned int npt = xyzs.values().size()/ 44 //unsigned int npt = xyzs.values().size()/3; 45 //::printf("debug : vertices : %lu : creat 45 //::printf("debug : vertices : %lu : create_gsto : %u\n",this,npt); 46 return a_mgr.create_gsto_from_data(xyzs.va 46 return a_mgr.create_gsto_from_data(xyzs.values()); 47 } 47 } 48 48 49 public: 49 public: 50 virtual void render(render_action& a_action) 50 virtual void render(render_action& a_action) { 51 if(touched()) {clean_gstos();reset_touched 51 if(touched()) {clean_gstos();reset_touched();} 52 if(xyzs.empty()) return; 52 if(xyzs.empty()) return; 53 53 54 const state& state = a_action.state(); 54 const state& state = a_action.state(); 55 55 56 if(state.m_use_gsto) { 56 if(state.m_use_gsto) { 57 unsigned int _id = get_gsto_id(a_action. 57 unsigned int _id = get_gsto_id(a_action.out(),a_action.render_manager()); 58 if(_id) { 58 if(_id) { 59 #ifdef __APPLE__ 59 #ifdef __APPLE__ 60 bool restore_blend = check_set_blend(a 60 bool restore_blend = check_set_blend(a_action); 61 #endif 61 #endif 62 a_action.begin_gsto(_id); 62 a_action.begin_gsto(_id); 63 size_t npt = xyzs.values().size()/3; 63 size_t npt = xyzs.values().size()/3; 64 bufpos pos = 0; 64 bufpos pos = 0; 65 if(gl::is_line(mode.value())) { 65 if(gl::is_line(mode.value())) { 66 //Same logic as Inventor SoLightMode 66 //Same logic as Inventor SoLightModel.model = BASE_COLOR. 67 a_action.set_lighting(false); 67 a_action.set_lighting(false); 68 a_action.draw_gsto_v(mode.value(),np 68 a_action.draw_gsto_v(mode.value(),npt,pos); 69 a_action.set_lighting(state.m_GL_LIG 69 a_action.set_lighting(state.m_GL_LIGHTING); 70 } else { 70 } else { 71 a_action.draw_gsto_v(mode.value(),np 71 a_action.draw_gsto_v(mode.value(),npt,pos); 72 } 72 } 73 a_action.end_gsto(); 73 a_action.end_gsto(); 74 #ifdef __APPLE__ 74 #ifdef __APPLE__ 75 if(restore_blend) a_action.set_blend(t 75 if(restore_blend) a_action.set_blend(true); 76 #endif 76 #endif 77 return; 77 return; 78 } else { //!_id 78 } else { //!_id 79 // use immediate rendering. 79 // use immediate rendering. 80 } 80 } 81 81 82 } else { 82 } else { 83 clean_gstos(&a_action.render_manager()); 83 clean_gstos(&a_action.render_manager()); 84 } 84 } 85 85 86 #ifdef __APPLE__ 86 #ifdef __APPLE__ 87 bool restore_blend = check_set_blend(a_act 87 bool restore_blend = check_set_blend(a_action); 88 #endif 88 #endif 89 89 90 // immediate rendering : 90 // immediate rendering : 91 if(gl::is_line(mode.value())) { 91 if(gl::is_line(mode.value())) { 92 //Same logic as Inventor SoLightModel.mo 92 //Same logic as Inventor SoLightModel.model = BASE_COLOR. 93 a_action.set_lighting(false); 93 a_action.set_lighting(false); 94 a_action.draw_vertex_array(mode.value(), 94 a_action.draw_vertex_array(mode.value(),xyzs.values()); 95 a_action.set_lighting(state.m_GL_LIGHTIN 95 a_action.set_lighting(state.m_GL_LIGHTING); 96 } else { 96 } else { 97 a_action.draw_vertex_array(mode.value(), 97 a_action.draw_vertex_array(mode.value(),xyzs.values()); 98 } 98 } 99 99 100 #ifdef __APPLE__ 100 #ifdef __APPLE__ 101 if(restore_blend) a_action.set_blend(true) 101 if(restore_blend) a_action.set_blend(true); 102 #endif 102 #endif 103 } 103 } 104 virtual void pick(pick_action& a_action) { 104 virtual void pick(pick_action& a_action) { 105 if(touched()) {clean_gstos();reset_touched 105 if(touched()) {clean_gstos();reset_touched();} 106 a_action.add__primitive(*this,mode.value() 106 a_action.add__primitive(*this,mode.value(),xyzs.values(),true); 107 } 107 } 108 108 109 virtual void bbox(bbox_action& a_action) { 109 virtual void bbox(bbox_action& a_action) { 110 if(touched()) {clean_gstos();reset_touched 110 if(touched()) {clean_gstos();reset_touched();} 111 a_action.add_points(xyzs.values()); 111 a_action.add_points(xyzs.values()); 112 } 112 } 113 virtual void is_visible(visible_action& a_ac 113 virtual void is_visible(visible_action& a_action) { 114 if(touched()) {clean_gstos();reset_touched 114 if(touched()) {clean_gstos();reset_touched();} 115 if(_is_visible(a_action)) a_action.increme 115 if(_is_visible(a_action)) a_action.increment(); 116 } 116 } 117 117 118 public: 118 public: 119 vertices() 119 vertices() 120 :parent() 120 :parent() 121 ,mode(gl::line_strip()){ 121 ,mode(gl::line_strip()){ 122 #ifdef TOOLS_MEM 122 #ifdef TOOLS_MEM 123 mem::increment(s_class().c_str()); 123 mem::increment(s_class().c_str()); 124 #endif 124 #endif 125 add_fields(); 125 add_fields(); 126 } 126 } 127 virtual ~vertices(){ 127 virtual ~vertices(){ 128 #ifdef TOOLS_MEM 128 #ifdef TOOLS_MEM 129 mem::decrement(s_class().c_str()); 129 mem::decrement(s_class().c_str()); 130 #endif 130 #endif 131 } 131 } 132 public: 132 public: 133 vertices(const vertices& a_from) 133 vertices(const vertices& a_from) 134 :parent(a_from) 134 :parent(a_from) 135 ,parent_gstos(a_from) 135 ,parent_gstos(a_from) 136 ,mode(a_from.mode) 136 ,mode(a_from.mode) 137 ,xyzs(a_from.xyzs) 137 ,xyzs(a_from.xyzs) 138 { 138 { 139 #ifdef TOOLS_MEM 139 #ifdef TOOLS_MEM 140 mem::increment(s_class().c_str()); 140 mem::increment(s_class().c_str()); 141 #endif 141 #endif 142 add_fields(); 142 add_fields(); 143 } 143 } 144 vertices& operator=(const vertices& a_from){ 144 vertices& operator=(const vertices& a_from){ 145 parent::operator=(a_from); 145 parent::operator=(a_from); 146 parent_gstos::operator=(a_from); 146 parent_gstos::operator=(a_from); 147 147 148 mode = a_from.mode; 148 mode = a_from.mode; 149 xyzs = a_from.xyzs; 149 xyzs = a_from.xyzs; 150 150 151 return *this; 151 return *this; 152 } 152 } 153 public: 153 public: 154 template <class VEC> 154 template <class VEC> 155 void add(const VEC& a_v) { 155 void add(const VEC& a_v) { 156 xyzs.add(a_v.x()); 156 xyzs.add(a_v.x()); 157 xyzs.add(a_v.y()); 157 xyzs.add(a_v.y()); 158 xyzs.add(a_v.z()); 158 xyzs.add(a_v.z()); 159 } 159 } 160 void add(float a_x,float a_y,float a_z) { 160 void add(float a_x,float a_y,float a_z) { 161 xyzs.add(a_x); 161 xyzs.add(a_x); 162 xyzs.add(a_y); 162 xyzs.add(a_y); 163 xyzs.add(a_z); 163 xyzs.add(a_z); 164 } 164 } 165 void add_allocated(size_t& a_pos,float a_x,f 165 void add_allocated(size_t& a_pos,float a_x,float a_y,float a_z) { 166 std::vector<float>& v = xyzs.values(); 166 std::vector<float>& v = xyzs.values(); 167 v[a_pos] = a_x;a_pos++; 167 v[a_pos] = a_x;a_pos++; 168 v[a_pos] = a_y;a_pos++; 168 v[a_pos] = a_y;a_pos++; 169 v[a_pos] = a_z;a_pos++; 169 v[a_pos] = a_z;a_pos++; 170 xyzs.touch(); 170 xyzs.touch(); 171 } 171 } 172 bool add(const std::vector<float>& a_v) { 172 bool add(const std::vector<float>& a_v) { 173 std::vector<float>::size_type _number = a_ 173 std::vector<float>::size_type _number = a_v.size()/3; 174 if(3*_number!=a_v.size()) return false; 174 if(3*_number!=a_v.size()) return false; 175 std::vector<float>::const_iterator it; 175 std::vector<float>::const_iterator it; 176 for(it=a_v.begin();it!=a_v.end();it+=3) { 176 for(it=a_v.begin();it!=a_v.end();it+=3) { 177 xyzs.add(*(it+0)); 177 xyzs.add(*(it+0)); 178 xyzs.add(*(it+1)); 178 xyzs.add(*(it+1)); 179 xyzs.add(*(it+2)); 179 xyzs.add(*(it+2)); 180 } 180 } 181 return true; 181 return true; 182 } 182 } 183 183 184 size_t number() const {return xyzs.size()/3; 184 size_t number() const {return xyzs.size()/3;} 185 void clear() {xyzs.clear();} 185 void clear() {xyzs.clear();} 186 186 187 bool add_dashed_line(float a_bx,float a_by,f 187 bool add_dashed_line(float a_bx,float a_by,float a_bz, 188 float a_ex,float a_ey,f 188 float a_ex,float a_ey,float a_ez, 189 unsigned int a_num_dash 189 unsigned int a_num_dash) { 190 //optimized version. 190 //optimized version. 191 if(!a_num_dash) return false; 191 if(!a_num_dash) return false; 192 // there is a dash at beg and end of line. 192 // there is a dash at beg and end of line. 193 193 194 float fac = 1.0f/float(2*a_num_dash-1); 194 float fac = 1.0f/float(2*a_num_dash-1); 195 float sx = (a_ex-a_bx)*fac; 195 float sx = (a_ex-a_bx)*fac; 196 float sy = (a_ey-a_by)*fac; 196 float sy = (a_ey-a_by)*fac; 197 float sz = (a_ez-a_bz)*fac; 197 float sz = (a_ez-a_bz)*fac; 198 198 199 float two_sx = sx*2.0f; 199 float two_sx = sx*2.0f; 200 float two_sy = sy*2.0f; 200 float two_sy = sy*2.0f; 201 float two_sz = sz*2.0f; 201 float two_sz = sz*2.0f; 202 202 203 float px = a_bx; 203 float px = a_bx; 204 float py = a_by; 204 float py = a_by; 205 float pz = a_bz; 205 float pz = a_bz; 206 206 207 for(unsigned int idash=0;idash<a_num_dash; 207 for(unsigned int idash=0;idash<a_num_dash;idash++) { 208 add(px,py,pz); 208 add(px,py,pz); 209 add(px+sx,py+sy,pz+sz); 209 add(px+sx,py+sy,pz+sz); 210 px += two_sx; 210 px += two_sx; 211 py += two_sy; 211 py += two_sy; 212 pz += two_sz; 212 pz += two_sz; 213 } 213 } 214 return true; 214 return true; 215 } 215 } 216 bool center() { 216 bool center() { 217 std::vector<float>& v = xyzs.values(); 217 std::vector<float>& v = xyzs.values(); 218 std::vector<float>::size_type _number = v. 218 std::vector<float>::size_type _number = v.size()/3; 219 if(!_number) return true; 219 if(!_number) return true; 220 if(3*_number!=v.size()) return false; 220 if(3*_number!=v.size()) return false; 221 float x_mean = 0; 221 float x_mean = 0; 222 float y_mean = 0; 222 float y_mean = 0; 223 float z_mean = 0; 223 float z_mean = 0; 224 {for(std::vector<float>::const_iterator it= 224 {for(std::vector<float>::const_iterator it=v.begin();it!=v.end();it+=3) { 225 x_mean += *(it+0); 225 x_mean += *(it+0); 226 y_mean += *(it+1); 226 y_mean += *(it+1); 227 z_mean += *(it+2); 227 z_mean += *(it+2); 228 }} 228 }} 229 x_mean /= float(_number); 229 x_mean /= float(_number); 230 y_mean /= float(_number); 230 y_mean /= float(_number); 231 z_mean /= float(_number); 231 z_mean /= float(_number); 232 {for(std::vector<float>::iterator it=v.begi 232 {for(std::vector<float>::iterator it=v.begin();it!=v.end();it+=3) { 233 *(it+0) -= x_mean; 233 *(it+0) -= x_mean; 234 *(it+1) -= y_mean; 234 *(it+1) -= y_mean; 235 *(it+2) -= z_mean; 235 *(it+2) -= z_mean; 236 }} 236 }} 237 return true; 237 return true; 238 } 238 } 239 protected: 239 protected: 240 bool _is_visible(const matrix_action& a_acti 240 bool _is_visible(const matrix_action& a_action) { 241 if(xyzs.empty()) return false; 241 if(xyzs.empty()) return false; 242 const state& _state = a_action.state(); 242 const state& _state = a_action.state(); 243 pick_action action(a_action.out(),_state.m 243 pick_action action(a_action.out(),_state.m_ww,_state.m_wh,0,float(_state.m_ww),0,float(_state.m_wh)); 244 action.set_win_size(_state.m_ww,_state.m_w 244 action.set_win_size(_state.m_ww,_state.m_wh); 245 action.set_area(0,float(_state.m_ww),0,flo 245 action.set_area(0,float(_state.m_ww),0,float(_state.m_wh)); 246 action.set_stop_at_first(true); 246 action.set_stop_at_first(true); 247 action.matrix_action::operator=(a_action); 247 action.matrix_action::operator=(a_action); //IMPORTANT. 248 int old_cur = action.cur(); //not 0. 248 int old_cur = action.cur(); //not 0. 249 action.add__primitive(*this,mode.value(),x 249 action.add__primitive(*this,mode.value(),xyzs.values(),true); 250 if(action.cur()!=old_cur) return false; 250 if(action.cur()!=old_cur) return false; 251 if(!action.node()) return false; 251 if(!action.node()) return false; 252 return true; 252 return true; 253 } 253 } 254 #ifdef __APPLE__ 254 #ifdef __APPLE__ 255 protected: 255 protected: 256 // macOS/Mojave : on this version, points ar 256 // macOS/Mojave : on this version, points are blended even if alpha is one ! 257 bool check_set_blend(render_action& a_action 257 bool check_set_blend(render_action& a_action) { 258 bool restore_blend = false; 258 bool restore_blend = false; 259 const state& state = a_action.state(); 259 const state& state = a_action.state(); 260 if(state.m_GL_BLEND) { 260 if(state.m_GL_BLEND) { 261 if(state.m_color.a()==1) { 261 if(state.m_color.a()==1) { 262 a_action.set_blend(false); 262 a_action.set_blend(false); 263 restore_blend = true; 263 restore_blend = true; 264 } 264 } 265 } 265 } 266 return restore_blend; 266 return restore_blend; 267 } 267 } 268 #endif //__APPLE__ 268 #endif //__APPLE__ 269 }; 269 }; 270 270 271 }} 271 }} 272 272 273 #endif 273 #endif