Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/sg/atb_vertices

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_sg_atb_vertices
  5 #define tools_sg_atb_vertices
  6 
  7 #include "vertices"
  8 
  9 namespace tools {
 10 namespace sg {
 11 
 12 class atb_vertices : public vertices {
 13   TOOLS_NODE(atb_vertices,tools::sg::atb_vertices,vertices)
 14 public:
 15   mf<float> rgbas;
 16   mf<float> nms;
 17   sf<bool> do_back;
 18   sf<float> epsilon;
 19   sf<bool> draw_edges;
 20 public:
 21   virtual const desc_fields& node_desc_fields() const {
 22     TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::atb_vertices)
 23     static const desc_fields s_v(parent::node_desc_fields(),5, //WARNING : take care of count.
 24       TOOLS_ARG_FIELD_DESC(rgbas),
 25       TOOLS_ARG_FIELD_DESC(nms),
 26       TOOLS_ARG_FIELD_DESC(do_back),
 27       TOOLS_ARG_FIELD_DESC(epsilon),
 28       TOOLS_ARG_FIELD_DESC(draw_edges)
 29     );
 30     return s_v;
 31   }
 32   virtual void protocol_one_fields(std::vector<field*>& a_fields) const {
 33     parent::protocol_one_fields(a_fields);
 34     const field* _draw_edges = static_cast<const field*>(&draw_edges);
 35     removep<field>(a_fields,_draw_edges);
 36   }
 37 private:
 38   void add_fields(){
 39     add_field(&rgbas);
 40     add_field(&nms);
 41     add_field(&do_back);
 42     add_field(&epsilon);
 43     add_field(&draw_edges);
 44   }
 45 protected: //gstos
 46   virtual unsigned int create_gsto(std::ostream&,sg::render_manager& a_mgr) {
 47     //unsigned int npt = xyzs.values().size()/3;
 48     //::printf("debug : atb_vertices : %lu : create_gsto : %u\n",this,npt);
 49 
 50     std::vector<float> gsto_data;
 51 
 52     if(rgbas.size()) {
 53       if(nms.size()) {
 54         if(do_back.value()) {
 55           append(gsto_data,xyzs.values());
 56           append(gsto_data,nms.values());
 57           append(gsto_data,m_back_xyzs);
 58           append(gsto_data,m_back_nms);
 59           append(gsto_data,rgbas.values());
 60         } else {
 61           append(gsto_data,xyzs.values());
 62           append(gsto_data,nms.values());
 63           append(gsto_data,rgbas.values());
 64         }
 65         if(draw_edges.value()) {
 66           // allocate edges :
 67           size_t pos_edges = gsto_data.size();
 68           append(gsto_data,xyzs.values());
 69           append(gsto_data,xyzs.values());
 70           float* pxyz = vec_data<float>(xyzs.values());
 71           float* pedges = vec_data<float>(gsto_data)+pos_edges;
 72           size_t npt = xyzs.values().size()/3;
 73           size_t ntri = npt/3;
 74           for(size_t itri=0;itri<ntri;itri++) {
 75             // first edge :
 76             *pedges = *(pxyz+0);pedges++;
 77             *pedges = *(pxyz+1);pedges++;
 78             *pedges = *(pxyz+2);pedges++;
 79 
 80             *pedges = *(pxyz+3);pedges++;
 81             *pedges = *(pxyz+4);pedges++;
 82             *pedges = *(pxyz+5);pedges++;
 83 
 84             // second edge :
 85             *pedges = *(pxyz+3);pedges++;
 86             *pedges = *(pxyz+4);pedges++;
 87             *pedges = *(pxyz+5);pedges++;
 88 
 89             *pedges = *(pxyz+6);pedges++;
 90             *pedges = *(pxyz+7);pedges++;
 91             *pedges = *(pxyz+8);pedges++;
 92 
 93             // third edge :
 94             *pedges = *(pxyz+6);pedges++;
 95             *pedges = *(pxyz+7);pedges++;
 96             *pedges = *(pxyz+8);pedges++;
 97 
 98             *pedges = *(pxyz+0);pedges++;
 99             *pedges = *(pxyz+1);pedges++;
100             *pedges = *(pxyz+2);pedges++;
101 
102             pxyz += 9;
103           }
104 
105         }
106       } else {
107         append(gsto_data,xyzs.values());
108         append(gsto_data,rgbas.values());
109       }
110     } else {
111       if(nms.size()) {
112         append(gsto_data,xyzs.values());
113         append(gsto_data,nms.values());
114       } else {
115         append(gsto_data,xyzs.values());
116       }
117     }
118     return a_mgr.create_gsto_from_data(gsto_data);
119   }
120 
121 public:
122   virtual void render(render_action& a_action) {
123     if(touched()) {
124       if(do_back.value()) gen_back();
125       if(draw_edges.value()) gen_edges();
126       m_all_a_one = true;
127      {tools_vforcit_npp(float,rgbas.values(),it) {
128         if(*(it+3)!=1) {m_all_a_one = false;break;}
129         it += 4;
130       }}
131       clean_gstos();
132       reset_touched();
133     }
134     if(xyzs.empty()) return;
135 
136     if(!have_to_render(a_action)) return;
137 
138     const state& state = a_action.state();
139 
140     if(state.m_use_gsto) {
141       unsigned int _id = get_gsto_id(a_action.out(),a_action.render_manager());
142       if(_id) {
143         a_action.begin_gsto(_id);
144         if(rgbas.size()) {
145 #ifdef __APPLE__
146           bool restore_blend = check_set_blend(a_action);
147 #endif
148           if(nms.size()) {
149             size_t npt = xyzs.values().size()/3;
150             bufpos pos_xyzs = 0;
151             bufpos pos_nms = 0;
152             bufpos pos_back_xyzs = 0;
153             bufpos pos_back_nms = 0;
154             bufpos pos_rgbas = 0;
155             bufpos pos_edges = 0;
156            {size_t sz = npt*3;
157             if(do_back.value()) {
158               pos_xyzs = 0;
159               pos_nms = pos_xyzs+sz*sizeof(float);  //bytes
160               pos_back_xyzs = pos_nms+sz*sizeof(float);
161               pos_back_nms = pos_back_xyzs+sz*sizeof(float);
162               pos_rgbas = pos_back_nms+sz*sizeof(float);
163             } else {
164               pos_xyzs = 0;
165               pos_nms = pos_xyzs+sz*sizeof(float);
166               pos_rgbas = pos_nms+sz*sizeof(float);
167             }}
168             if(draw_edges.value()) {
169               pos_edges = pos_rgbas+npt*4*sizeof(float);
170             }
171             if(gl::is_line(mode.value())) {
172               //Same logic as Inventor SoLightModel.model = BASE_COLOR.
173               a_action.set_lighting(false);
174               if(do_back.value()) a_action.draw_gsto_vcn(mode.value(),npt,pos_back_xyzs,pos_rgbas,pos_back_nms);
175               a_action.draw_gsto_vcn(mode.value(),npt,pos_xyzs,pos_rgbas,pos_nms);
176               a_action.set_lighting(state.m_GL_LIGHTING);
177             } else if(mode.value()==gl::triangles()) {
178               if(draw_edges.value()) {
179                 a_action.color4f(0,0,0,1);
180                 a_action.line_width(1);
181                 a_action.draw_gsto_v(gl::lines(),2*npt,pos_edges);
182                 //pushes back the filled polygons to avoid z-fighting with lines
183                 a_action.set_polygon_offset(true);
184 
185                 a_action.color4f(state.m_color);
186                 a_action.line_width(state.m_line_width);
187                 //a_action.set_lighting(state.m_GL_LIGHTING);
188               }
189               if(do_back.value()) a_action.draw_gsto_vcn(mode.value(),npt,pos_back_xyzs,pos_rgbas,pos_back_nms);
190               a_action.draw_gsto_vcn(mode.value(),npt,pos_xyzs,pos_rgbas,pos_nms);
191               if(draw_edges.value()) a_action.set_polygon_offset(state.m_GL_POLYGON_OFFSET_FILL);
192             } else {
193               if(do_back.value()) a_action.draw_gsto_vcn(mode.value(),npt,pos_back_xyzs,pos_rgbas,pos_back_nms);
194               a_action.draw_gsto_vcn(mode.value(),npt,pos_xyzs,pos_rgbas,pos_nms);
195             }
196 
197           } else {
198             size_t npt = xyzs.values().size()/3;
199             bufpos pos_xyzs = 0;
200             bufpos pos_rgbas = npt*3*sizeof(float);
201             if(gl::is_line(mode.value())) {
202               //Same logic as Inventor SoLightModel.model = BASE_COLOR.
203               a_action.set_lighting(false);
204               a_action.draw_gsto_vc(mode.value(),npt,pos_xyzs,pos_rgbas);
205               a_action.set_lighting(state.m_GL_LIGHTING);
206             } else {
207               a_action.draw_gsto_vc(mode.value(),npt,pos_xyzs,pos_rgbas);
208             }
209           }
210 #ifdef __APPLE__
211           if(restore_blend) a_action.set_blend(true);
212 #endif
213         } else { //rgbas.empty()
214           if(nms.size()) {
215             size_t npt = xyzs.values().size()/3;
216             bufpos pos_xyzs = 0;
217             bufpos pos_nms = npt*3*sizeof(float);
218             if(gl::is_line(mode.value())) {
219               //Same logic as Inventor SoLightModel.model = BASE_COLOR.
220               a_action.set_lighting(false);
221               a_action.draw_gsto_vn(mode.value(),npt,pos_xyzs,pos_nms);
222               a_action.set_lighting(state.m_GL_LIGHTING);
223             } else {
224               a_action.draw_gsto_vn(mode.value(),npt,pos_xyzs,pos_nms);
225             }
226           } else {
227             size_t npt = xyzs.values().size()/3;
228             bufpos pos = 0;
229             if(gl::is_line(mode.value())) {
230               //Same logic as Inventor SoLightModel.model = BASE_COLOR.
231               a_action.set_lighting(false);
232               a_action.draw_gsto_v(mode.value(),npt,pos);
233               a_action.set_lighting(state.m_GL_LIGHTING);
234             } else {
235               a_action.draw_gsto_v(mode.value(),npt,pos);
236             }
237           }
238         }
239         a_action.end_gsto();
240         return;
241 
242       } else { //!_id
243         // use immediate rendering.
244       }
245 
246     } else {
247       clean_gstos(&a_action.render_manager());
248     }
249 
250     // immediate rendering :
251     if(rgbas.size()) {
252 
253 #ifdef __APPLE__
254       bool restore_blend = check_set_blend(a_action);
255 #endif
256 
257       if(nms.size()) {
258           if(gl::is_line(mode.value())) {
259             //Same logic as Inventor SoLightModel.model = BASE_COLOR.
260             a_action.set_lighting(false);
261             if(do_back.value())
262               a_action.draw_vertex_color_normal_array(mode.value(),m_back_xyzs,rgbas.values(),m_back_nms);
263             a_action.draw_vertex_color_normal_array(mode.value(),xyzs.values(),rgbas.values(),nms.values());
264             a_action.set_lighting(state.m_GL_LIGHTING);
265           } else if(mode.value()==gl::triangles()) {
266             if(draw_edges.value()) {
267               a_action.color4f(0,0,0,1);
268               a_action.line_width(1);
269               a_action.draw_vertex_array(gl::lines(),m_edges);
270               a_action.set_polygon_offset(true);
271               a_action.color4f(state.m_color);
272               a_action.line_width(state.m_line_width);
273             }
274             if(do_back.value()) a_action.draw_vertex_color_normal_array(mode.value(),m_back_xyzs,rgbas.values(),m_back_nms);
275             a_action.draw_vertex_color_normal_array(mode.value(),xyzs.values(),rgbas.values(),nms.values());
276             if(draw_edges.value()) a_action.set_polygon_offset(state.m_GL_POLYGON_OFFSET_FILL);
277           } else {
278             if(do_back.value()) a_action.draw_vertex_color_normal_array(mode.value(),m_back_xyzs,rgbas.values(),m_back_nms);
279             a_action.draw_vertex_color_normal_array(mode.value(),xyzs.values(),rgbas.values(),nms.values());
280           }
281 
282       } else {
283           if(gl::is_line(mode.value())) {
284             //Same logic as Inventor SoLightModel.model = BASE_COLOR.
285             a_action.set_lighting(false);
286             a_action.draw_vertex_color_array(mode.value(),xyzs.values(),rgbas.values());
287             a_action.set_lighting(state.m_GL_LIGHTING);
288           } else {
289             a_action.draw_vertex_color_array(mode.value(),xyzs.values(),rgbas.values());
290           }
291       }
292 
293 #ifdef __APPLE__
294       if(restore_blend) a_action.set_blend(true);
295 #endif
296     } else { //rgbas.empty()
297       if(nms.size()) {
298           if(gl::is_line(mode.value())) {
299             //Same logic as Inventor SoLightModel.model = BASE_COLOR.
300             a_action.set_lighting(false);
301             a_action.draw_vertex_normal_array(mode.value(),xyzs.values(),nms.values());
302             a_action.set_lighting(state.m_GL_LIGHTING);
303           } else {
304             a_action.draw_vertex_normal_array(mode.value(),xyzs.values(),nms.values());
305           }
306       } else {
307           if(gl::is_line(mode.value())) {
308             //Same logic as Inventor SoLightModel.model = BASE_COLOR.
309             a_action.set_lighting(false);
310             a_action.draw_vertex_array(mode.value(),xyzs.values());
311             a_action.set_lighting(state.m_GL_LIGHTING);
312           } else {
313             a_action.draw_vertex_array(mode.value(),xyzs.values());
314           }
315       }
316 
317     }
318 
319   }
320 public:
321   atb_vertices()
322   :parent()
323   ,do_back(false)
324   ,epsilon(0)
325   ,draw_edges(false)
326   ,m_xyzs_pos(0)
327   ,m_rgbas_pos(0)
328   ,m_nms_pos(0)
329   ,m_all_a_one(true)
330   {
331 #ifdef TOOLS_MEM
332     mem::increment(s_class().c_str());
333 #endif
334     add_fields();
335   }
336   virtual ~atb_vertices(){
337 #ifdef TOOLS_MEM
338     mem::decrement(s_class().c_str());
339 #endif
340   }
341 public:
342   atb_vertices(const atb_vertices& a_from)
343   :parent(a_from)
344   ,rgbas(a_from.rgbas)
345   ,nms(a_from.nms)
346   ,do_back(a_from.do_back)
347   ,epsilon(a_from.epsilon)
348   ,draw_edges(a_from.draw_edges)
349   ,m_xyzs_pos(a_from.m_xyzs_pos)
350   ,m_rgbas_pos(a_from.m_rgbas_pos)
351   ,m_nms_pos(a_from.m_nms_pos)
352   ,m_all_a_one(true)
353   {
354 #ifdef TOOLS_MEM
355     mem::increment(s_class().c_str());
356 #endif
357     add_fields();
358   }
359   atb_vertices& operator=(const atb_vertices& a_from){
360     parent::operator=(a_from);
361     rgbas = a_from.rgbas;
362     nms = a_from.nms;
363     do_back = a_from.do_back;
364     epsilon = a_from.epsilon;
365     draw_edges = a_from.draw_edges;
366     m_xyzs_pos = a_from.m_xyzs_pos;
367     m_rgbas_pos = a_from.m_rgbas_pos;
368     m_nms_pos = a_from.m_nms_pos;
369     return *this;
370   }
371 public:
372   void add_pos_color(float a_x,float a_y,float a_z,float a_r,float a_g,float a_b,float a_a) {
373     xyzs.add(a_x);
374     xyzs.add(a_y);
375     xyzs.add(a_z);
376     rgbas.add(a_r);
377     rgbas.add(a_g);
378     rgbas.add(a_b);
379     rgbas.add(a_a);
380   }
381 
382   template <class COLOR>
383   void add_pos_color(float a_x,float a_y,float a_z,const COLOR& a_col) {
384     xyzs.add(a_x);
385     xyzs.add(a_y);
386     xyzs.add(a_z);
387     rgbas.add(a_col.r());
388     rgbas.add(a_col.g());
389     rgbas.add(a_col.b());
390     rgbas.add(a_col.a());
391   }
392 
393   template <class VEC,class COLOR>
394   void add_pos_color(const VEC& a_pos,const COLOR& a_col) {
395     xyzs.add(a_pos.x());
396     xyzs.add(a_pos.y());
397     xyzs.add(a_pos.z());
398     rgbas.add(a_col.r());
399     rgbas.add(a_col.g());
400     rgbas.add(a_col.b());
401     rgbas.add(a_col.a());
402   }
403 
404   void allocate_pos_color(size_t a_npt) {
405     xyzs.values().resize(a_npt*3);
406     rgbas.values().resize(a_npt*4);
407     m_xyzs_pos = 0;
408     m_rgbas_pos = 0;
409   }
410 
411   template <class VEC,class COLOR>
412   void add_pos_color_allocated(const VEC& a_pos,const COLOR& a_col) {
413    {std::vector<float>& v = xyzs.values();
414     v[m_xyzs_pos] = a_pos.x();m_xyzs_pos++;
415     v[m_xyzs_pos] = a_pos.y();m_xyzs_pos++;
416     v[m_xyzs_pos] = a_pos.z();m_xyzs_pos++;
417     xyzs.touch();}
418    {std::vector<float>& v = rgbas.values();
419     v[m_rgbas_pos] = a_col.r();m_rgbas_pos++;
420     v[m_rgbas_pos] = a_col.g();m_rgbas_pos++;
421     v[m_rgbas_pos] = a_col.b();m_rgbas_pos++;
422     v[m_rgbas_pos] = a_col.a();m_rgbas_pos++;
423     rgbas.touch();}
424   }
425 
426   template <class VEC,class COLOR>
427   void add_pos_color_normal(const VEC& a_pos,const COLOR& a_col,const VEC& a_nm) {
428     xyzs.add(a_pos.x());
429     xyzs.add(a_pos.y());
430     xyzs.add(a_pos.z());
431     rgbas.add(a_col.r());
432     rgbas.add(a_col.g());
433     rgbas.add(a_col.b());
434     rgbas.add(a_col.a());
435     nms.add(a_nm.x());
436     nms.add(a_nm.y());
437     nms.add(a_nm.z());
438   }
439 
440   void allocate_pos_color_normal(size_t a_npt) {
441     xyzs.values().resize(a_npt*3);
442     rgbas.values().resize(a_npt*4);
443     nms.values().resize(a_npt*3);
444     m_xyzs_pos = 0;
445     m_rgbas_pos = 0;
446     m_nms_pos = 0;
447   }
448 
449   template <class VEC,class COLOR>
450   void add_pos_color_normal_allocated(const VEC& a_pos,const COLOR& a_col,const VEC& a_nm) {
451    {std::vector<float>& v = xyzs.values();
452     v[m_xyzs_pos] = a_pos.x();m_xyzs_pos++;
453     v[m_xyzs_pos] = a_pos.y();m_xyzs_pos++;
454     v[m_xyzs_pos] = a_pos.z();m_xyzs_pos++;
455     xyzs.touch();}
456    {std::vector<float>& v = rgbas.values();
457     v[m_rgbas_pos] = a_col.r();m_rgbas_pos++;
458     v[m_rgbas_pos] = a_col.g();m_rgbas_pos++;
459     v[m_rgbas_pos] = a_col.b();m_rgbas_pos++;
460     v[m_rgbas_pos] = a_col.a();m_rgbas_pos++;
461     rgbas.touch();}
462    {std::vector<float>& v = nms.values();
463     v[m_nms_pos] = a_nm.x();m_nms_pos++;
464     v[m_nms_pos] = a_nm.y();m_nms_pos++;
465     v[m_nms_pos] = a_nm.z();m_nms_pos++;
466     nms.touch();}
467   }
468 
469   void add_rgba(float a_r,float a_g,float a_b,float a_a) {
470     rgbas.add(a_r);
471     rgbas.add(a_g);
472     rgbas.add(a_b);
473     rgbas.add(a_a);
474   }
475   void add_color(const colorf& a_col) {
476     rgbas.add(a_col.r());
477     rgbas.add(a_col.g());
478     rgbas.add(a_col.b());
479     rgbas.add(a_col.a());
480   }
481 
482   void add_normal(float a_x,float a_y,float a_z) {
483     nms.add(a_x);
484     nms.add(a_y);
485     nms.add(a_z);
486   }
487   template <class VEC>
488   void add_normal(const VEC& a_nm) {
489     nms.add(a_nm.x());
490     nms.add(a_nm.y());
491     nms.add(a_nm.z());
492   }
493 
494   void add_rgba_allocated(size_t& a_pos,float a_r,float a_g,float a_b,float a_a) {
495     std::vector<float>& v = rgbas.values();
496     v[a_pos] = a_r;a_pos++;
497     v[a_pos] = a_g;a_pos++;
498     v[a_pos] = a_b;a_pos++;
499     v[a_pos] = a_a;a_pos++;
500     rgbas.touch();
501   }
502   void add_normal_allocated(size_t& a_pos,float a_x,float a_y,float a_z) {
503     std::vector<float>& v = nms.values();
504     v[a_pos] = a_x;a_pos++;
505     v[a_pos] = a_y;a_pos++;
506     v[a_pos] = a_z;a_pos++;
507     nms.touch();
508   }
509 
510   template <class VEC>
511   void add_pos_normal(const VEC& a_pos,const VEC& a_nm) {
512     xyzs.add(a_pos.x());
513     xyzs.add(a_pos.y());
514     xyzs.add(a_pos.z());
515     nms.add(a_nm.x());
516     nms.add(a_nm.y());
517     nms.add(a_nm.z());
518   }
519 
520   bool add_dashed_line_rgba(float a_bx,float a_by,float a_bz,
521                             float a_ex,float a_ey,float a_ez,
522                             unsigned int a_num_dash,
523                             float a_r,float a_g,float a_b,float a_a) {
524     if(!parent::add_dashed_line(a_bx,a_by,a_bz,a_ex,a_ey,a_ez,a_num_dash)) return false;
525     for(unsigned int index=0;index<a_num_dash;index++) {
526       add_rgba(a_r,a_g,a_b,a_a);
527       add_rgba(a_r,a_g,a_b,a_a);
528     }
529     return true;
530   }
531 
532   void clear() {
533     rgbas.clear();
534     nms.clear();
535     parent::clear();
536   }
537 protected:
538   bool have_to_render(render_action& a_action) {
539     bool transparent = false;
540     if(rgbas.size()) {
541       if(!m_all_a_one) transparent = true;
542     } else {
543       if(a_action.state().m_color.a()!=1) transparent = true;
544     }
545     if(transparent) {
546       if(a_action.do_transparency()) return true;
547       a_action.set_have_to_do_transparency(true);
548       return false;
549     } else {
550       if(a_action.do_transparency()) return false;
551     }
552     return true;
553   }
554     
555   void gen_back(){
556     m_back_xyzs.clear();
557     m_back_nms.clear();
558 
559     clean_gstos(); //must reset for all render_manager.
560 
561     std::vector<float>& _xyzs = xyzs.values();
562     std::vector<float>& _nms = nms.values();
563 
564     if(_xyzs.empty()) return;
565 
566     m_back_xyzs.resize(_xyzs.size(),0);
567     m_back_nms.resize(_nms.size(),0);
568 
569     float epsil = epsilon.value();
570 
571     if(mode.value()==gl::triangle_fan()) { //reverse after first point.
572 
573       m_back_xyzs[0] = _xyzs[0] - _nms[0] * epsil;
574       m_back_xyzs[1] = _xyzs[1] - _nms[1] * epsil;
575       m_back_xyzs[2] = _xyzs[2] - _nms[2] * epsil;
576 
577      {std::vector<float>::const_iterator it = _xyzs.begin()+3;
578       std::vector<float>::const_iterator _end = _xyzs.end();
579       std::vector<float>::const_iterator itn = _nms.begin()+3;
580       std::vector<float>::reverse_iterator it2 = m_back_xyzs.rbegin();
581       for(;it!=_end;it2+=3) {
582         *(it2+2) = *it - *itn * epsil; it++;itn++; //x
583         *(it2+1) = *it - *itn * epsil; it++;itn++; //y
584         *(it2+0) = *it - *itn * epsil; it++;itn++; //z
585       }}
586 
587       m_back_nms[0] = _nms[0] * -1.0f;
588       m_back_nms[1] = _nms[1] * -1.0f;
589       m_back_nms[2] = _nms[2] * -1.0f;
590 
591      {std::vector<float>::const_iterator it = _nms.begin()+3;
592       std::vector<float>::const_iterator _end = _nms.end();
593       std::vector<float>::reverse_iterator it2 = m_back_nms.rbegin();
594       for(;it!=_end;it2+=3) {
595         *(it2+2) = *it * -1.0f; it++;
596         *(it2+1) = *it * -1.0f; it++;
597         *(it2+0) = *it * -1.0f; it++;
598       }}
599 
600     } else {
601 
602      {std::vector<float>::const_iterator it = _xyzs.begin();
603       std::vector<float>::const_iterator _end = _xyzs.end();
604       std::vector<float>::const_iterator itn = _nms.begin();
605       std::vector<float>::reverse_iterator it2 = m_back_xyzs.rbegin();
606       for(;it!=_end;it2+=3) {
607         *(it2+2) = *it - *itn * epsil; it++;itn++; //x
608         *(it2+1) = *it - *itn * epsil; it++;itn++; //y
609         *(it2+0) = *it - *itn * epsil; it++;itn++; //z
610       }}
611 
612      {std::vector<float>::const_iterator it = _nms.begin();
613       std::vector<float>::const_iterator _end = _nms.end();
614       std::vector<float>::reverse_iterator it2 = m_back_nms.rbegin();
615       for(;it!=_end;it2+=3) {
616         *(it2+2) = *it * -1.0f; it++;
617         *(it2+1) = *it * -1.0f; it++;
618         *(it2+0) = *it * -1.0f; it++;
619       }}
620 
621     }
622   }
623 
624   void gen_edges(){
625     m_edges.clear();
626 
627     clean_gstos(); //must reset for all render_manager.
628 
629     std::vector<float>& _xyzs = xyzs.values();
630     if(_xyzs.empty()) return;
631 
632     m_edges.resize(2*_xyzs.size(),0);
633 
634     float* pxyz = vec_data<float>(xyzs.values());
635     float* pedges = vec_data<float>(m_edges);
636 
637     size_t npt = xyzs.values().size()/3;
638     size_t ntri = npt/3;
639     for(size_t itri=0;itri<ntri;itri++) {
640       // first edge :
641       *pedges = *(pxyz+0);pedges++;
642       *pedges = *(pxyz+1);pedges++;
643       *pedges = *(pxyz+2);pedges++;
644 
645       *pedges = *(pxyz+3);pedges++;
646       *pedges = *(pxyz+4);pedges++;
647       *pedges = *(pxyz+5);pedges++;
648 
649       // second edge :
650       *pedges = *(pxyz+3);pedges++;
651       *pedges = *(pxyz+4);pedges++;
652       *pedges = *(pxyz+5);pedges++;
653 
654       *pedges = *(pxyz+6);pedges++;
655       *pedges = *(pxyz+7);pedges++;
656       *pedges = *(pxyz+8);pedges++;
657 
658       // third edge :
659       *pedges = *(pxyz+6);pedges++;
660       *pedges = *(pxyz+7);pedges++;
661       *pedges = *(pxyz+8);pedges++;
662 
663       *pedges = *(pxyz+0);pedges++;
664       *pedges = *(pxyz+1);pedges++;
665       *pedges = *(pxyz+2);pedges++;
666 
667       pxyz += 9;
668     }
669   }
670 #ifdef __APPLE__
671 protected:
672   // macOS/Mojave : on this version, points are blended even if alpha is one !
673   bool check_set_blend(render_action& a_action) {
674     bool restore_blend = false;
675     const state& state = a_action.state();
676     if(state.m_GL_BLEND) {
677     /*
678       bool all_a_one = true;
679       tools_vforcit_npp(float,rgbas.values(),it) {
680         if(*(it+3)!=1) {all_a_one = false;break;}
681         it += 4;
682       }
683       if(all_a_one) {
684         a_action.set_blend(false);
685         restore_blend = true;
686       }
687       */
688       if(m_all_a_one) {
689         a_action.set_blend(false);
690         restore_blend = true;
691       }
692     }
693     return restore_blend;
694   }
695 #endif
696 protected:
697   std::vector<float> m_back_xyzs;
698   std::vector<float> m_back_nms;
699   std::vector<float> m_edges;
700 protected:
701   size_t m_xyzs_pos;
702   size_t m_rgbas_pos;
703   size_t m_nms_pos;
704   bool m_all_a_one;
705 };
706 
707 }}
708 
709 #endif