g4tools  5.4.0
polyhedron
Go to the documentation of this file.
1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
2 // See the file tools.license for terms.
3 
4 #ifndef tools_sg_polyhedron
5 #define tools_sg_polyhedron
6 
7 #include "node"
8 #include "sf"
9 #include "render_action"
10 #include "pick_action"
11 #include "bbox_action"
12 #include "state"
13 #include "render_manager"
14 #include "gstos"
15 #include "../hep/sf_polyhedron"
16 #include "../vmanip"
17 
18 #include "tessellate"
19 
20 namespace tools {
21 namespace sg {
22 
23 class polyhedron : public node, public gstos {
25 public:
30 public:
31  virtual const desc_fields& node_desc_fields() const {
33  static const desc_fields s_v(parent::node_desc_fields(),4, //WARNING : take care of count.
38  );
39  return s_v;
40  }
41 private:
42  void add_fields(){
43  add_field(&ph);
44  add_field(&solid);
47  }
48 public: //node
49 
51 
52 protected: //gstos
53  virtual unsigned int create_gsto(std::ostream& a_out,render_manager& a_mgr) {
54  m_size = 0;
55  if(solid.value()) {
56 
57  size_t sz = 0;
58 
59  if(m_draw_edges) sz += m_xyzs.size();
60 
62  const prims_t& prims = *itt;
63  tools_vforcit(tess_prim*,prims,it) {
64  const tess_prim& item = *(*it);
65  const std::vector<float>& coords = item.m_coords;
66  const std::vector<float>& norms = item.m_norms;
67  if(coords.empty()) continue;
68  if(norms.size()!=coords.size()) {
69  a_out << "tools::sg::polyhedron::create_gsto :"
70  << " bad number of normals."
71  << std::endl;
72  continue;
73  }
74  sz += coords.size()+norms.size();
75  }
76  }}
77 
78  if(sz) {
79 
80  float* buffer = new float[sz];
81  char* pos = (char*)buffer;
82  size_t psz = 0;
83 
84  if(m_draw_edges) {
85  if(m_xyzs.size()) {
86  size_t _sz = m_xyzs.size()*sizeof(float);
87  ::memcpy(pos,vec_data<float>(m_xyzs),_sz);
88  pos += _sz;
89  psz += _sz;
90  m_size = m_xyzs.size();
91  //m_xyzs.clear(); //we need them for pick,write,...
92  }
93  }
94 
96  const prims_t& prims = *itt;
97  tools_vforcit(tess_prim*,prims,it) {
98  tess_prim& item = *(*it);
99  const std::vector<float>& coords = item.m_coords;
100  const std::vector<float>& norms = item.m_norms;
101  if(coords.empty()) continue;
102  if(norms.size()!=coords.size()) continue;
103 
104  item.m_size = coords.size();
105 
106  {item.m_pos_coords = psz;
107  size_t _sz = coords.size()*sizeof(float);
108  ::memcpy(pos,vec_data<float>(coords),_sz);
109  pos += _sz;
110  psz += _sz;}
111 
112  {item.m_pos_norms = psz;
113  size_t _sz = norms.size()*sizeof(float);
114  ::memcpy(pos,vec_data<float>(norms),_sz);
115  pos += _sz;
116  psz += _sz;}
117 
118  // we don't need coords, norms for rendering
119  // but needed for pick,write...
120  //coords.clear();
121  //norms.clear();
122 
123  //we still need m_prims.
124 
125  }
126  }}
127 
128  unsigned int id = a_mgr.create_gsto_from_data(sz,buffer);
129  delete [] buffer;
130  return id;
131  }
132 
133  } else {
134  m_size = m_xyzs.size();
135  return a_mgr.create_gsto_from_data(m_xyzs);
136  }
137  return 0;
138  }
139 
140 public:
141  virtual void render(render_action& a_action) {
142  const state& state = a_action.state();
143 
144  bool draw_edges = false;
145  if(solid.value()) {
146  draw_edges = state.m_GL_LIGHTING?false:true;
147  if(enforce_edges.value()) draw_edges = true;
148  }
149 
150  if( touched() ||
151  (draw_edges && m_xyzs.empty()) ||
152  (solid.value() && m_primss.empty()) ){
154  if(solid.value()) what = draw_edges?faces_and_lines:faces;
155  update_sg(a_action.out(),what);
156  reset_touched();
157  }
158 
159  unsigned int _id = 0;
160  if(state.m_use_gsto) {
161  m_draw_edges = draw_edges;
162  _id = get_gsto_id(a_action.out(),a_action.render_manager());
163  } else {
164  clean_gstos(&a_action.render_manager());
165  }
166 
167  //a_action.out() << "debug : tools::sg::polyhedron::render_action :"
168  // << " m_xyzs.size() " << m_xyzs.size()
169  // << " m_primss.size() " << m_primss.size()
170  // << std::endl;
171 
172  if(solid.value()) {
173 
174  if(_id) {
175 
176  a_action.begin_gsto(_id);
177  if(draw_edges && m_size) {
178  //Same logic as Inventor SoLightModel.model = BASE_COLOR.
179  a_action.set_lighting(false);
180  a_action.color4f(0,0,0,1);
181 
182  a_action.draw_gsto_v(gl::lines(),m_size/3,0);
183 
184  //pushes back the filled polygons to avoid z-fighting with lines
185  a_action.set_polygon_offset(true);
186 
187  a_action.color4f(state.m_color);
188  a_action.set_lighting(state.m_GL_LIGHTING);
189  }
190 
192  const prims_t& prims = *itt;
193  tools_vforcit(tess_prim*,prims,it) {
194  const tess_prim& item = *(*it);
195  a_action.draw_gsto_vn(item.m_mode,item.m_size/3,item.m_pos_coords,item.m_pos_norms);
196  }
197  }}
198 
200  a_action.end_gsto();
201  } else {
202 
203  if(draw_edges){
204  if(m_xyzs.size()) {
205  //Same logic as Inventor SoLightModel.model = BASE_COLOR.
206  a_action.set_lighting(false);
207  a_action.color4f(0,0,0,1);
208 
209  a_action.draw_vertex_array(gl::lines(),m_xyzs);
210 
211  //pushes back the filled polygons to avoid z-fighting with lines
212  a_action.set_polygon_offset(true);
213 
214  a_action.color4f(state.m_color);
215  a_action.set_lighting(state.m_GL_LIGHTING);
216  }
217  }
218 
220  const prims_t& prims = *itt;
221  tools_vforcit(tess_prim*,prims,it) {
222  const tess_prim& item = *(*it);
223  const std::vector<float>& coords = item.m_coords;
224  if(coords.empty()) continue;
225  const std::vector<float>& norms = item.m_norms;
226  if(norms.size()!=coords.size()) {
227  a_action.out() << "tools::sg::polyhedron::render :"
228  << " bad number of normals."
229  << std::endl;
230  continue;
231  }
232  a_action.draw_vertex_normal_array(item.m_mode,coords,norms);
233  }
234  }}
236  }
237 
238  } else { //not solid
239  //Same logic as Inventor SoLightModel.model = BASE_COLOR.
240  a_action.set_lighting(false); // do we want that ?
241 
242  if(_id) {
243  a_action.begin_gsto(_id);
244  a_action.draw_gsto_v(gl::lines(),m_size/3,0);
245  a_action.end_gsto();
246  } else {
247  a_action.draw_vertex_array(gl::lines(),m_xyzs);
248  }
249 
250  a_action.set_lighting(state.m_GL_LIGHTING);
251  }
252  }
253 
254  virtual void bbox(bbox_action& a_action) {
255  if(touched()) {
256  update_sg(a_action.out(),lines);
257  reset_touched();
258  }
259  if(solid.value()) {
261  const prims_t& prims = *itt;
262  tools_vforcit(tess_prim*,prims,it) {
263  const tess_prim& item = *(*it);
264  const std::vector<float>& coords = item.m_coords;
265  a_action.add_points(coords);
266  }
267  }
268  } else {
269  a_action.add_points(m_xyzs);
270  }
271  }
272 
273  virtual void pick(pick_action& a_action) {
274  if(touched()) {
276  update_sg(a_action.out(),what);
277  reset_touched();
278  }
279  if(solid.value()) {
281  const prims_t& prims = *itt;
282  tools_vforcit(tess_prim*,prims,it) {
283  const tess_prim& item = *(*it);
284  const std::vector<float>& coords = item.m_coords;
285  if(a_action.add__primitive(*this,item.m_mode,coords,true)) return;
286  }
287  }
288  } else {
289  a_action.add__lines(*this,m_xyzs,true);
290  }
291  }
292 public:
294  :parent()
295  ,ph(hep::polyhedron())
296  ,solid(true)
297  ,reduced_wire_frame(true)
298  ,enforce_edges(false)
299 
300  ,m_tess(0)
301  {
302  add_fields();
303  }
304  virtual ~polyhedron(){
305  _clear();
306  delete m_tess;
307  }
308 public:
309  polyhedron(const polyhedron& a_from)
310  :parent(a_from)
311  ,gstos(a_from)
312  ,ph(a_from.ph)
313  ,solid(a_from.solid)
316 
317  ,m_xyzs(a_from.m_xyzs)
318  ,m_tess(0)
319  {
320  add_fields();
321  }
322  polyhedron& operator=(const polyhedron& a_from){
323  parent::operator=(a_from);
324  gstos::operator=(a_from);
325  ph = a_from.ph;
326  solid = a_from.solid;
328  enforce_edges = a_from.enforce_edges;
329 
330  m_xyzs = a_from.m_xyzs;
331 
332  return *this;
333  }
334 
335 public:
336  enum update_what {
337  faces = 0,
338  lines = 1,
340  };
341 
342  void update_sg(std::ostream& a_out,const update_what& a_what) {
343  //a_out << "debug : tools::sg::polyhedron::update_sg" << std::endl;
344 
345  clean_gstos(); //must reset for all render_manager.
346 
347  _clear();
348 
349  const hep::polyhedron& sbPolyhedron = ph.value();
350  if(sbPolyhedron.GetNoFacets()<=0) {
351  //a_out << "tools::sg::polyhedron::update_sg : abnormal polyhedron." << std::endl;
352  return; // Abnormal polyhedron.
353  }
354 
355  if((a_what==faces)||(a_what==faces_and_lines)) {
356 
357  std::vector<double> doubles;
358 
359  vec3d unitNormal;
360  vec3d* pV = sbPolyhedron.GetPV();
361 
362  // Assume all facets are convex quadrilaterals :
363  bool notLastFace;
364  do {
365  notLastFace = sbPolyhedron.GetNextUnitNormal(unitNormal);
366 
367  doubles.clear(); //begin POLYGON
368 
369  bool notLastEdge;
370  int edgeFlag = 1;
371  do {
372  // optimize to avoid copying vec3f.
373  //notLastEdge = sbPolyhedron.GetNextVertex(vertex,edgeFlag);
374  int index;
375  notLastEdge = sbPolyhedron.GetNextVertexIndex(index,edgeFlag);
376  vec3d* vertex = pV+index; //WARNING : must not be modified !
377 
378  doubles.push_back((*vertex)[0]);
379  doubles.push_back((*vertex)[1]);
380  doubles.push_back((*vertex)[2]);
381 
382  } while (notLastEdge);
383 
384  if(!m_tess) m_tess = new tessellate(a_out);
385 
386  m_primss.push_back(prims_t());
387  prims_t& prims = m_primss.back();
388 
389  m_tess->do_it(doubles.size()/3,vec_data(doubles),prims);
390 
391  m_tess->clear();
392 
393  } while (notLastFace);
394  }
395 
396  if((a_what==lines)||(a_what==faces_and_lines)) {
397  float pvbx = 0;
398  float pvby = 0;
399  float pvbz = 0;
400 
401  float pvex,pvey,pvez;
402 
403  vec3d unitNormal;
404  vec3d* pV = sbPolyhedron.GetPV();
405 
406  bool notLastFace;
407  do {
408  notLastFace = sbPolyhedron.GetNextUnitNormal(unitNormal);
409 
410  // Treat edges :
411  int edgeFlag = 1;
412  int prevEdgeFlag = edgeFlag;
413  bool notLastEdge;
414  bool firstEdge = true;
415  do {
416  int index;
417  notLastEdge = sbPolyhedron.GetNextVertexIndex(index,edgeFlag);
418  vec3d* vertex = pV+index; //WARNING : must not be modified !
419 
420  if(!reduced_wire_frame) edgeFlag = 1;
421  if(firstEdge) {
422  if(edgeFlag) {
423  pvbx = (float)(*vertex)[0];
424  pvby = (float)(*vertex)[1];
425  pvbz = (float)(*vertex)[2];
426  } else {
427  }
428  firstEdge = false;
429  prevEdgeFlag = edgeFlag;
430  } else {
431  if(edgeFlag!=prevEdgeFlag) {
432  if(edgeFlag) { // Pass to a visible edge :
433  pvbx = (float)(*vertex)[0];
434  pvby = (float)(*vertex)[1];
435  pvbz = (float)(*vertex)[2];
436  } else { // Pass to an invisible edge :
437  pvex = (float)(*vertex)[0];
438  pvey = (float)(*vertex)[1];
439  pvez = (float)(*vertex)[2];
440 
441  m_xyzs.push_back(pvbx);
442  m_xyzs.push_back(pvby);
443  m_xyzs.push_back(pvbz);
444 
445  m_xyzs.push_back(pvex);
446  m_xyzs.push_back(pvey);
447  m_xyzs.push_back(pvez);
448  }
449  prevEdgeFlag = edgeFlag;
450  } else {
451  if(edgeFlag) {
452  pvex = (float)(*vertex)[0];
453  pvey = (float)(*vertex)[1];
454  pvez = (float)(*vertex)[2];
455 
456  m_xyzs.push_back(pvbx);
457  m_xyzs.push_back(pvby);
458  m_xyzs.push_back(pvbz);
459 
460  m_xyzs.push_back(pvex);
461  m_xyzs.push_back(pvey);
462  m_xyzs.push_back(pvez);
463 
464  pvbx = pvex;
465  pvby = pvey;
466  pvbz = pvez;
467  } else {
468  }
469  }
470  }
471  } while (notLastEdge);
472  } while (notLastFace);
473 
474  }
475  }
476 
477  const std::vector<float>& xyzs() const {return m_xyzs;}
478 
479 protected:
480  void _clear(){
482  m_primss.clear();
483  m_xyzs.clear();
484  }
485 
486 protected:
487  std::vector<float> m_xyzs;
488 
489  //gluTess
491  std::vector<prims_t> m_primss;
492 
493  size_t m_size;
495 };
496 
497 }}
498 
499 #endif
tools::sg::polyhedron::update_what
update_what
Definition: polyhedron:336
tools::sg::gstos
Definition: gstos:16
node
tools::sg::polyhedron::reduced_wire_frame
sf< bool > reduced_wire_frame
Definition: polyhedron:28
tools::sg::render_action::draw_gsto_v
virtual void draw_gsto_v(gl::mode_t, size_t, bufpos)=0
tools::sg::render_action::draw_vertex_array
virtual void draw_vertex_array(gl::mode_t, size_t, const float *)=0
tools::sg::state
Definition: state:25
tools::sg::render_action::set_lighting
virtual void set_lighting(bool)=0
tools::hep::polyhedron::GetNextVertexIndex
bool GetNextVertexIndex(int &index, int &edgeFlag) const
Definition: polyhedron:446
tools::sg::state::m_GL_LIGHTING
bool m_GL_LIGHTING
Definition: state:248
tools::sg::polyhedron::polyhedron
polyhedron(const polyhedron &a_from)
Definition: polyhedron:309
tools::vec3d
Definition: vec3d:13
pick_action
tools::vec_data
const T * vec_data(const std::vector< T > &a_vec)
Definition: vdata:18
tools::sg::polyhedron::m_tess
tessellate * m_tess
Definition: polyhedron:490
tools::sg::tess_prim::m_size
size_t m_size
Definition: tessellate:68
render_action
tools::sg::polyhedron::bbox
virtual void bbox(bbox_action &a_action)
Definition: polyhedron:254
tools::sg::state::m_GL_POLYGON_OFFSET_FILL
bool m_GL_POLYGON_OFFSET_FILL
Definition: state:250
tools::sg::polyhedron::xyzs
const std::vector< float > & xyzs() const
Definition: polyhedron:477
tools::sg::polyhedron::node_desc_fields
virtual const desc_fields & node_desc_fields() const
Definition: polyhedron:31
tools::sg::gstos::clean_gstos
void clean_gstos()
Definition: gstos:89
tools::sg::node
Definition: node:28
tools::sg::polyhedron::polyhedron
polyhedron()
Definition: polyhedron:293
tools::gl::lines
mode_t lines()
Definition: glprims:17
tools::sg::bbox_action
Definition: bbox_action:15
TOOLS_NODE
#define TOOLS_NODE(a__class, a__sclass, a__parent)
Definition: node:324
tools::sg::tessellate::prims_t
std::vector< tess_prim * > prims_t
Definition: tessellate:142
tools::sg::polyhedron::operator=
polyhedron & operator=(const polyhedron &a_from)
Definition: polyhedron:322
tools::hep::polyhedron
Definition: polyhedron:142
tools::raw_clear
void raw_clear(std::map< K, V * > &a_m)
Definition: mapmanip:56
tools::hep::polyhedron::GetNoFacets
int GetNoFacets() const
Definition: polyhedron:253
tools::sg::desc_fields
Definition: field_desc:148
tools::sg::render_action::color4f
virtual void color4f(float, float, float, float)=0
tools::sg::gstos::operator=
gstos & operator=(const gstos &a_from)
Definition: gstos:22
tools::sg::polyhedron::m_primss
std::vector< prims_t > m_primss
Definition: polyhedron:491
tools::sg::polyhedron::~polyhedron
virtual ~polyhedron()
Definition: polyhedron:304
tools::sg::polyhedron::faces
@ faces
Definition: polyhedron:337
tools::sg::pick_action
Definition: pick_action:59
tools::sg::pick_action::add__primitive
bool add__primitive(sg::node &a_node, gl::mode_t a_mode, size_t a_floatn, const float *a_xyzs, bool a_stop=false)
Definition: pick_action:431
tools::sg::render_manager::create_gsto_from_data
virtual unsigned int create_gsto_from_data(size_t, const float *)=0
render_manager
tools::sg::state::m_use_gsto
bool m_use_gsto
Definition: state:256
tools::sg::render_manager
Definition: render_manager:16
tools::sg::tess_prim::m_pos_coords
bufpos m_pos_coords
Definition: tessellate:70
tools::sg::render_action::set_polygon_offset
virtual void set_polygon_offset(bool)=0
tools::sg::render_action::render_manager
virtual sg::render_manager & render_manager()=0
sf
tools::sg::tess_prim::m_norms
std::vector< float > m_norms
Definition: tessellate:66
tools::sg::polyhedron::m_draw_edges
bool m_draw_edges
Definition: polyhedron:494
tools::sg::primitive_visitor::add_points
bool add_points(size_t a_floatn, const float *a_xyzs, bool a_stop=false)
Definition: primitive_visitor:1405
gstos
tools_vforit
#define tools_vforit(a__T, a__v, a__it)
Definition: forit:13
tools::sg::render_action
Definition: render_action:24
tools::sg::gstos::get_gsto_id
unsigned int get_gsto_id(std::ostream &a_out, render_manager &a_mgr)
Definition: gstos:60
tools::sg::polyhedron::_clear
void _clear()
Definition: polyhedron:480
tools::sg::render_action::begin_gsto
virtual void begin_gsto(gstoid)=0
VBO /////////////////////////////////////////////////////////.
tools::sg::tessellate::do_it
void do_it(size_t a_npt, const double *a_contour, prims_t &a_prims)
Definition: tessellate:143
tools::sg::render_action::draw_gsto_vn
virtual void draw_gsto_vn(gl::mode_t, size_t, bufpos, bufpos)=0
tools
inlined C code : ///////////////////////////////////
Definition: aida_ntuple:26
tools::sg::node::add_field
void add_field(field *a_field)
Definition: node:128
tools::sg::tessellate::clear
void clear()
Definition: tessellate:157
tools::sg::render_action::end_gsto
virtual void end_gsto()=0
tools::sg::polyhedron::solid
sf< bool > solid
Definition: polyhedron:27
TOOLS_FIELD_DESC_NODE_CLASS
#define TOOLS_FIELD_DESC_NODE_CLASS(a__class)
Definition: field:68
tools::sg::tess_prim::m_pos_norms
bufpos m_pos_norms
Definition: tessellate:71
tools::sg::pick_action::add__lines
bool add__lines(sg::node &a_node, const std::vector< float > &a_xyzs, bool a_stop=false)
Definition: pick_action:518
tools::sg::polyhedron::ph
hep::sf_polyhedron ph
Definition: polyhedron:26
tools::sg::polyhedron::enforce_edges
sf< bool > enforce_edges
Definition: polyhedron:29
tools::sg::polyhedron
Definition: polyhedron:23
tools::hep::polyhedron::GetNextUnitNormal
bool GetNextUnitNormal(HVNormal3D &normal) const
tools::sg::polyhedron::m_xyzs
std::vector< float > m_xyzs
Definition: polyhedron:487
tools::sg::render_action::draw_vertex_normal_array
virtual void draw_vertex_normal_array(gl::mode_t, size_t, const float *, const float *)=0
tools::sg::bsf::value
T & value()
Definition: bsf:98
tools::sg::polyhedron::render
virtual void render(render_action &a_action)
Definition: polyhedron:141
tools::sg::action::out
std::ostream & out() const
Definition: action:51
tools::sg::polyhedron::create_gsto
virtual unsigned int create_gsto(std::ostream &a_out, render_manager &a_mgr)
Definition: polyhedron:53
tools::sg::state::m_color
colorf m_color
Definition: state:259
tools::sg::polyhedron::m_size
size_t m_size
Definition: polyhedron:493
tools::what
what
Definition: strip:12
tools_vforcit
#define tools_vforcit(a__T, a__v, a__it)
Definition: forit:7
tools::sg::polyhedron::prims_t
tessellate::prims_t prims_t
Definition: polyhedron:50
tools::hep::polyhedron::GetPV
HVPoint3D * GetPV() const
Definition: polyhedron:269
tools::sg::polyhedron::update_sg
void update_sg(std::ostream &a_out, const update_what &a_what)
Definition: polyhedron:342
tools::sg::states::state
const sg::state & state() const
Definition: states:76
tessellate
state
tools::sg::polyhedron::lines
@ lines
Definition: polyhedron:338
tools::sg::node::touched
virtual bool touched()
Definition: node:96
tools::sg::polyhedron::pick
virtual void pick(pick_action &a_action)
Definition: polyhedron:273
tools::sg::polyhedron::faces_and_lines
@ faces_and_lines
Definition: polyhedron:339
tools::sg::tess_prim
Definition: tessellate:20
tools::sg::sf< bool >
TOOLS_ARG_FIELD_DESC
#define TOOLS_ARG_FIELD_DESC(a__field)
Definition: field:71
tools::sg::tess_prim::m_mode
gl::mode_t m_mode
Definition: tessellate:64
tools::sg::tess_prim::m_coords
std::vector< float > m_coords
Definition: tessellate:65
tools::sg::node::reset_touched
virtual void reset_touched()
Definition: node:102
tools::sg::tessellate
Definition: tessellate:92
bbox_action
tools::hep::sf_polyhedron
Definition: sf_polyhedron:17