Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/sg/primitive_visitor is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_sg_primitive_visitor
0005 #define tools_sg_primitive_visitor
0006 
0007 #include "../glprims"
0008 
0009 // for texture :
0010 #include "../lina/vec2f"
0011 #include "../lina/vec3f"
0012 #include "../img"
0013 #include "../lina/geom2"
0014 
0015 namespace tools {
0016 namespace sg {
0017 
0018 class primitive_visitor {
0019 protected:
0020   virtual bool project(float& a_x,float& a_y,float& a_z,float& a_w) = 0;
0021 
0022   virtual bool add_point(float,float,float,float) = 0;  //xyzw
0023   virtual bool add_point(float,float,float,float,
0024                          float,float,float,float) = 0;  //xyzw & rgbas
0025 
0026   virtual bool add_line(float,float,float,float,
0027                         float,float,float,float) = 0;  // 2 xyzw
0028   virtual bool add_line(float,float,float,float, float,float,float,float,
0029                         float,float,float,float, float,float,float,float) = 0;  // 2 (xyzw & rgba)
0030 
0031   virtual bool add_triangle(float,float,float,float,
0032                             float,float,float,float,
0033                             float,float,float,float) = 0;  // 3 xyzw
0034   virtual bool add_triangle(float,float,float,float, float,float,float,float,
0035                             float,float,float,float, float,float,float,float,
0036                             float,float,float,float, float,float,float,float) = 0;  // 3 (xywz & rgba)
0037 
0038   virtual bool project_normal(float& a_x,float& a_y,float& a_z) = 0;
0039   virtual bool add_point_normal(float,float,float,float,
0040                                 float,float,float) = 0;
0041   virtual bool add_point_normal(float,float,float,float,
0042                                 float,float,float,
0043                                 float,float,float,float) = 0;
0044   virtual bool add_line_normal(float,float,float,float, float,float,float,
0045                                float,float,float,float, float,float,float) = 0;
0046   virtual bool add_line_normal(float,float,float,float, float,float,float, float,float,float,float,
0047                                float,float,float,float, float,float,float, float,float,float,float) = 0;
0048   virtual bool add_triangle_normal(float,float,float,float, float,float,float,
0049                                    float,float,float,float, float,float,float,
0050                                    float,float,float,float, float,float,float) = 0;
0051   virtual bool add_triangle_normal(float,float,float,float, float,float,float, float,float,float,float,
0052                                    float,float,float,float, float,float,float, float,float,float,float,
0053                                    float,float,float,float, float,float,float, float,float,float,float) = 0;
0054 public:
0055   primitive_visitor():m_mode(gl::points()){}
0056   virtual ~primitive_visitor(){}
0057 public:
0058   primitive_visitor(const primitive_visitor&):m_mode(gl::points()){}
0059   primitive_visitor& operator=(const primitive_visitor&){return *this;}
0060 public:
0061   void add_one_point(float a_x,float a_y,float a_z) {
0062     float w;
0063     project(a_x,a_y,a_z,w);
0064     add_point(a_x,a_y,a_z,w);
0065   }
0066   void add_one_point(float a_x,float a_y,float a_z,float a_r,float a_g,float a_b,float a_a) {
0067     float w;
0068     project(a_x,a_y,a_z,w);
0069     add_point(a_x,a_y,a_z,w,a_r,a_g,a_b,a_a);
0070   }
0071 
0072   bool add_triangle_fan(size_t a_floatn,const float* a_xyzs,bool a_stop = false){
0073     size_t num = a_floatn/3;
0074     if(num<3) return false;
0075 
0076     m_mode = gl::triangle_fan();
0077 
0078     float p1x,p1y,p1z,w1=1;
0079     float p2x,p2y,p2z,w2=1;
0080     float p3x,p3y,p3z,w3=1;
0081 
0082     const float* pos1 = a_xyzs+3*0;
0083     p1x = *(pos1+0);
0084     p1y = *(pos1+1);
0085     p1z = *(pos1+2);
0086     project(p1x,p1y,p1z,w1);
0087 
0088     const float* pos2 = a_xyzs+3*1;
0089     p2x = *(pos2+0);
0090     p2y = *(pos2+1);
0091     p2z = *(pos2+2);
0092     project(p2x,p2y,p2z,w2);
0093 
0094     for(size_t index=2;index<num;index++) {
0095       const float* pos = a_xyzs+3*index;
0096       p3x = *(pos+0);
0097       p3y = *(pos+1);
0098       p3z = *(pos+2);
0099       project(p3x,p3y,p3z,w3);
0100 
0101       if(!add_triangle(p1x,p1y,p1z,w1,
0102                        p2x,p2y,p2z,w2,
0103                        p3x,p3y,p3z,w3)) {
0104         if(a_stop) return false;
0105       }
0106 
0107       p2x = p3x;
0108       p2y = p3y;
0109       p2z = p3z;
0110       w2 = w3;
0111     }
0112     return true;
0113   }
0114 
0115   bool add_triangle_fan_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms,bool a_stop = false){
0116     size_t num = a_floatn/3;
0117     if(num<3) return false;
0118 
0119     m_mode = gl::triangle_fan();
0120 
0121     float p1x,p1y,p1z,w1=1;
0122     float p2x,p2y,p2z,w2=1;
0123     float p3x,p3y,p3z,w3=1;
0124 
0125     const float* pos1 = a_xyzs+3*0;
0126     p1x = *(pos1+0);
0127     p1y = *(pos1+1);
0128     p1z = *(pos1+2);
0129     project(p1x,p1y,p1z,w1);
0130 
0131     const float* pos2 = a_xyzs+3*1;
0132     p2x = *(pos2+0);
0133     p2y = *(pos2+1);
0134     p2z = *(pos2+2);
0135     project(p2x,p2y,p2z,w2);
0136 
0137     float n1x,n1y,n1z;
0138     float n2x,n2y,n2z;
0139     float n3x,n3y,n3z;
0140 
0141     const float* nos1 = a_nms+3*0;
0142     n1x = *(nos1+0);
0143     n1y = *(nos1+1);
0144     n1z = *(nos1+2);
0145     project_normal(n1x,n1y,n1z);
0146 
0147     const float* nos2 = a_nms+3*1;
0148     n2x = *(nos2+0);
0149     n2y = *(nos2+1);
0150     n2z = *(nos2+2);
0151     project_normal(n2x,n2y,n2z);
0152 
0153     for(size_t index=2;index<num;index++) {
0154       const float* pos = a_xyzs+3*index;
0155       p3x = *(pos+0);
0156       p3y = *(pos+1);
0157       p3z = *(pos+2);
0158       project(p3x,p3y,p3z,w3);
0159 
0160       const float* nos = a_nms+3*index;
0161       n3x = *(nos+0);
0162       n3y = *(nos+1);
0163       n3z = *(nos+2);
0164       project_normal(n1x,n1y,n1z);
0165 
0166       if(!add_triangle_normal(p1x,p1y,p1z,w1, n1x,n1y,n1z,
0167                               p2x,p2y,p2z,w2, n2x,n2y,n2z,
0168                               p3x,p3y,p3z,w3, n3x,n3y,n3z)) {
0169         if(a_stop) return false;
0170       }
0171 
0172       p2x = p3x;
0173       p2y = p3y;
0174       p2z = p3z;
0175       w2 = w3;
0176 
0177       n2x = n3x;
0178       n2y = n3y;
0179       n2z = n3z;
0180     }
0181     return true;
0182   }
0183 
0184   bool add_triangle_fan_normal_rgba(size_t a_floatn,const float* a_xyzs,const float* a_nms,const float* a_rgbas,bool a_stop = false){
0185     size_t num = a_floatn/3;
0186     if(num<3) return false;
0187 
0188     m_mode = gl::triangle_fan();
0189 
0190     float p1x,p1y,p1z,w1=1;
0191     float p2x,p2y,p2z,w2=1;
0192     float p3x,p3y,p3z,w3=1;
0193 
0194     float r1,g1,b1,a1;
0195     float r2,g2,b2,a2;
0196     float r3,g3,b3,a3;
0197 
0198     const float* pos1 = a_xyzs+3*0;
0199     p1x = *(pos1+0);
0200     p1y = *(pos1+1);
0201     p1z = *(pos1+2);
0202     project(p1x,p1y,p1z,w1);
0203 
0204     const float* pos2 = a_xyzs+3*1;
0205     p2x = *(pos2+0);
0206     p2y = *(pos2+1);
0207     p2z = *(pos2+2);
0208     project(p2x,p2y,p2z,w2);
0209 
0210     float n1x,n1y,n1z;
0211     float n2x,n2y,n2z;
0212     float n3x,n3y,n3z;
0213 
0214     const float* nos1 = a_nms+3*0;
0215     n1x = *(nos1+0);
0216     n1y = *(nos1+1);
0217     n1z = *(nos1+2);
0218     project_normal(n1x,n1y,n1z);
0219 
0220     const float* nos2 = a_nms+3*1;
0221     n2x = *(nos2+0);
0222     n2y = *(nos2+1);
0223     n2z = *(nos2+2);
0224     project_normal(n2x,n2y,n2z);
0225 
0226     const float* ros1 = a_rgbas+4*0;
0227     r1 = *ros1;ros1++;
0228     g1 = *ros1;ros1++;
0229     b1 = *ros1;ros1++;
0230     a1 = *ros1;ros1++;
0231 
0232     const float* ros2 = a_rgbas+4*1;
0233     r2 = *ros2;ros2++;
0234     g2 = *ros2;ros2++;
0235     b2 = *ros2;ros2++;
0236     a2 = *ros2;ros2++;
0237 
0238     for(size_t index=2;index<num;index++) {
0239       const float* pos = a_xyzs+3*index;
0240       p3x = *(pos+0);
0241       p3y = *(pos+1);
0242       p3z = *(pos+2);
0243       project(p3x,p3y,p3z,w3);
0244 
0245       const float* nos = a_nms+3*index;
0246       n3x = *(nos+0);
0247       n3y = *(nos+1);
0248       n3z = *(nos+2);
0249       project_normal(n1x,n1y,n1z);
0250 
0251       const float* ros = a_rgbas+4*index;
0252       r3 = *ros;ros++;
0253       g3 = *ros;ros++;
0254       b3 = *ros;ros++;
0255       a3 = *ros;ros++;
0256 
0257       if(!add_triangle_normal(p1x,p1y,p1z,w1, n1x,n1y,n1z, r1,b1,g1,a1,
0258                               p2x,p2y,p2z,w2, n2x,n2y,n2z, r2,b2,g2,a2,
0259                               p3x,p3y,p3z,w3, n3x,n3y,n3z, r3,b3,g3,a3)) {
0260         if(a_stop) return false;
0261       }
0262 
0263       p2x = p3x;
0264       p2y = p3y;
0265       p2z = p3z;
0266       w2 = w3;
0267 
0268       n2x = n3x;
0269       n2y = n3y;
0270       n2z = n3z;
0271 
0272       r2 = r3;
0273       g2 = g3;
0274       b2 = b3;
0275       a2 = a3;
0276     }
0277     return true;
0278   }
0279 
0280   bool add_triangle_strip(size_t a_floatn,const float* a_xyzs,bool a_stop = false){
0281     size_t num = a_floatn/3;
0282     if(num<3) return false;
0283 
0284     m_mode = gl::triangle_strip();
0285 
0286     float p1x,p1y,p1z,w1=1;
0287     float p2x,p2y,p2z,w2=1;
0288     float p3x,p3y,p3z,w3=1;
0289 
0290     const float* pos1 = a_xyzs+3*0;
0291     p1x = *(pos1+0);
0292     p1y = *(pos1+1);
0293     p1z = *(pos1+2);
0294     project(p1x,p1y,p1z,w1);
0295 
0296     const float* pos2 = a_xyzs+3*1;
0297     p2x = *(pos2+0);
0298     p2y = *(pos2+1);
0299     p2z = *(pos2+2);
0300     project(p2x,p2y,p2z,w2);
0301 
0302     bool flip = false;
0303     for(size_t index=2;index<num;index++) {
0304       const float* pos = a_xyzs+3*index;
0305       p3x = *(pos+0);
0306       p3y = *(pos+1);
0307       p3z = *(pos+2);
0308       project(p3x,p3y,p3z,w3);
0309 
0310       if(flip){
0311         if(!add_triangle(p1x,p1y,p1z,w1,
0312                          p3x,p3y,p3z,w3,
0313                          p2x,p2y,p2z,w2)) {
0314           if(a_stop) return false;
0315         }
0316       } else {
0317         if(!add_triangle(p1x,p1y,p1z,w1,
0318                          p2x,p2y,p2z,w2,
0319                          p3x,p3y,p3z,w3)) {
0320           if(a_stop) return false;
0321         }
0322       }
0323 
0324       p1x = p2x;
0325       p1y = p2y;
0326       p1z = p2z;
0327       w1 = w2;
0328 
0329       p2x = p3x;
0330       p2y = p3y;
0331       p2z = p3z;
0332       w2 = w3;
0333 
0334       flip = flip?false:true;
0335     }
0336     return true;
0337   }
0338 
0339   bool add_triangles(size_t a_floatn,const float* a_xyzs,bool a_stop = false){
0340     size_t num = a_floatn/3;
0341     if(num<3) return false;
0342 
0343     m_mode = gl::triangles();
0344 
0345     float p1x,p1y,p1z,w1=1;
0346     float p2x,p2y,p2z,w2=1;
0347     float p3x,p3y,p3z,w3=1;
0348 
0349     for(size_t index=0;index<num;index+=3) {
0350 
0351       const float* pos = a_xyzs+3*index;
0352 
0353       p1x = *pos;pos++;
0354       p1y = *pos;pos++;
0355       p1z = *pos;pos++;
0356       project(p1x,p1y,p1z,w1);
0357 
0358       p2x = *pos;pos++;
0359       p2y = *pos;pos++;
0360       p2z = *pos;pos++;
0361       project(p2x,p2y,p2z,w2);
0362 
0363       p3x = *pos;pos++;
0364       p3y = *pos;pos++;
0365       p3z = *pos;pos++;
0366       project(p3x,p3y,p3z,w3);
0367 
0368       if(!add_triangle(p1x,p1y,p1z,w1,
0369                        p2x,p2y,p2z,w2,
0370                        p3x,p3y,p3z,w3)) {
0371         if(a_stop) return false;
0372       }
0373     }
0374     return true;
0375   }
0376 
0377   bool add_triangle_strip_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms,bool a_stop = false){
0378     size_t num = a_floatn/3;
0379     if(num<3) return false;
0380 
0381     m_mode = gl::triangle_strip();
0382 
0383     float p1x,p1y,p1z,w1=1;
0384     float p2x,p2y,p2z,w2=1;
0385     float p3x,p3y,p3z,w3=1;
0386 
0387     const float* pos1 = a_xyzs+3*0;
0388     p1x = *(pos1+0);
0389     p1y = *(pos1+1);
0390     p1z = *(pos1+2);
0391     project(p1x,p1y,p1z,w1);
0392 
0393     const float* pos2 = a_xyzs+3*1;
0394     p2x = *(pos2+0);
0395     p2y = *(pos2+1);
0396     p2z = *(pos2+2);
0397     project(p2x,p2y,p2z,w2);
0398 
0399     float n1x,n1y,n1z;
0400     float n2x,n2y,n2z;
0401     float n3x,n3y,n3z;
0402 
0403     const float* nos1 = a_nms+3*0;
0404     n1x = *(nos1+0);
0405     n1y = *(nos1+1);
0406     n1z = *(nos1+2);
0407     project_normal(n1x,n1y,n1z);
0408 
0409     const float* nos2 = a_nms+3*1;
0410     n2x = *(nos2+0);
0411     n2y = *(nos2+1);
0412     n2z = *(nos2+2);
0413     project_normal(n2x,n2y,n2z);
0414 
0415     bool flip = false;
0416     for(size_t index=2;index<num;index++) {
0417       const float* pos = a_xyzs+3*index;
0418       p3x = *(pos+0);
0419       p3y = *(pos+1);
0420       p3z = *(pos+2);
0421       project(p3x,p3y,p3z,w3);
0422 
0423       const float* nos = a_nms+3*index;
0424       n3x = *(nos+0);
0425       n3y = *(nos+1);
0426       n3z = *(nos+2);
0427       project_normal(n1x,n1y,n1z);
0428 
0429       if(flip){
0430         if(!add_triangle_normal(p1x,p1y,p1z,w1, n1x,n1y,n1z,
0431                                 p3x,p3y,p3z,w3, n3x,n3y,n3z,
0432                                 p2x,p2y,p2z,w2, n2x,n2y,n2z)) {
0433           if(a_stop) return false;
0434         }
0435       } else {
0436         if(!add_triangle_normal(p1x,p1y,p1z,w1, n1x,n1y,n1z,
0437                                 p2x,p2y,p2z,w2, n2x,n2y,n2z,
0438                                 p3x,p3y,p3z,w3, n3x,n3y,n3z)) {
0439           if(a_stop) return false;
0440         }
0441       }
0442 
0443       p1x = p2x;
0444       p1y = p2y;
0445       p1z = p2z;
0446       w1 = w2;
0447 
0448       p2x = p3x;
0449       p2y = p3y;
0450       p2z = p3z;
0451       w2 = w3;
0452 
0453       n1x = n2x;
0454       n1y = n2y;
0455       n1z = n2z;
0456 
0457       n2x = n3x;
0458       n2y = n3y;
0459       n2z = n3z;
0460 
0461       flip = flip?false:true;
0462     }
0463     return true;
0464   }
0465 
0466   bool add_triangle_strip_normal_rgba(size_t a_floatn,const float* a_xyzs,const float* a_nms,const float* a_rgbas,bool a_stop = false){
0467     size_t num = a_floatn/3;
0468     if(num<3) return false;
0469 
0470     m_mode = gl::triangle_strip();
0471 
0472     float p1x,p1y,p1z,w1=1;
0473     float p2x,p2y,p2z,w2=1;
0474     float p3x,p3y,p3z,w3=1;
0475 
0476     float r1,g1,b1,a1;
0477     float r2,g2,b2,a2;
0478     float r3,g3,b3,a3;
0479 
0480     const float* pos1 = a_xyzs+3*0;
0481     p1x = *(pos1+0);
0482     p1y = *(pos1+1);
0483     p1z = *(pos1+2);
0484     project(p1x,p1y,p1z,w1);
0485 
0486     const float* pos2 = a_xyzs+3*1;
0487     p2x = *(pos2+0);
0488     p2y = *(pos2+1);
0489     p2z = *(pos2+2);
0490     project(p2x,p2y,p2z,w2);
0491 
0492     float n1x,n1y,n1z;
0493     float n2x,n2y,n2z;
0494     float n3x,n3y,n3z;
0495 
0496     const float* nos1 = a_nms+3*0;
0497     n1x = *(nos1+0);
0498     n1y = *(nos1+1);
0499     n1z = *(nos1+2);
0500     project_normal(n1x,n1y,n1z);
0501 
0502     const float* nos2 = a_nms+3*1;
0503     n2x = *(nos2+0);
0504     n2y = *(nos2+1);
0505     n2z = *(nos2+2);
0506     project_normal(n2x,n2y,n2z);
0507 
0508     const float* ros1 = a_rgbas+4*0;
0509     r1 = *ros1;ros1++;
0510     g1 = *ros1;ros1++;
0511     b1 = *ros1;ros1++;
0512     a1 = *ros1;ros1++;
0513 
0514     const float* ros2 = a_rgbas+4*1;
0515     r2 = *ros2;ros2++;
0516     g2 = *ros2;ros2++;
0517     b2 = *ros2;ros2++;
0518     a2 = *ros2;ros2++;
0519 
0520     bool flip = false;
0521     for(size_t index=2;index<num;index++) {
0522       const float* pos = a_xyzs+3*index;
0523       p3x = *(pos+0);
0524       p3y = *(pos+1);
0525       p3z = *(pos+2);
0526       project(p3x,p3y,p3z,w3);
0527 
0528       const float* nos = a_nms+3*index;
0529       n3x = *(nos+0);
0530       n3y = *(nos+1);
0531       n3z = *(nos+2);
0532       project_normal(n1x,n1y,n1z);
0533 
0534       const float* ros = a_rgbas+4*index;
0535       r3 = *ros;ros++;
0536       g3 = *ros;ros++;
0537       b3 = *ros;ros++;
0538       a3 = *ros;ros++;
0539 
0540       if(flip){
0541         if(!add_triangle_normal(p1x,p1y,p1z,w1, n1x,n1y,n1z, r1,g1,b1,a1,
0542                                 p3x,p3y,p3z,w3, n3x,n3y,n3z, r3,g3,b3,a3,
0543                                 p2x,p2y,p2z,w2, n2x,n2y,n2z, r2,g2,b2,a2)) {
0544           if(a_stop) return false;
0545         }
0546       } else {
0547         if(!add_triangle_normal(p1x,p1y,p1z,w1, n1x,n1y,n1z, r1,g1,b1,a1,
0548                                 p2x,p2y,p2z,w2, n2x,n2y,n2z, r2,g2,b2,a2,
0549                                 p3x,p3y,p3z,w3, n3x,n3y,n3z, r3,g3,b3,a3)) {
0550           if(a_stop) return false;
0551         }
0552       }
0553 
0554       p1x = p2x;
0555       p1y = p2y;
0556       p1z = p2z;
0557       w1 = w2;
0558 
0559       p2x = p3x;
0560       p2y = p3y;
0561       p2z = p3z;
0562       w2 = w3;
0563 
0564       n1x = n2x;
0565       n1y = n2y;
0566       n1z = n2z;
0567 
0568       n2x = n3x;
0569       n2y = n3y;
0570       n2z = n3z;
0571 
0572       r1 = r2;
0573       g1 = g2;
0574       b1 = b2;
0575       a1 = a2;
0576 
0577       r2 = r3;
0578       g2 = g3;
0579       b2 = b3;
0580       a2 = a3;
0581 
0582       flip = flip?false:true;
0583     }
0584     return true;
0585   }
0586 
0587   bool add_triangles_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms,bool a_stop = false){
0588     size_t num = a_floatn/3;
0589     if(num<3) return false;
0590 
0591     m_mode = gl::triangles();
0592 
0593     float p1x,p1y,p1z,w1=1;
0594     float p2x,p2y,p2z,w2=1;
0595     float p3x,p3y,p3z,w3=1;
0596 
0597     float n1x,n1y,n1z;
0598     float n2x,n2y,n2z;
0599     float n3x,n3y,n3z;
0600 
0601     for(size_t index=0;index<num;index+=3) {
0602 
0603       const float* pos = a_xyzs+3*index;
0604 
0605       p1x = *pos;pos++;
0606       p1y = *pos;pos++;
0607       p1z = *pos;pos++;
0608       project(p1x,p1y,p1z,w1);
0609 
0610       p2x = *pos;pos++;
0611       p2y = *pos;pos++;
0612       p2z = *pos;pos++;
0613       project(p2x,p2y,p2z,w2);
0614 
0615       p3x = *pos;pos++;
0616       p3y = *pos;pos++;
0617       p3z = *pos;pos++;
0618       project(p3x,p3y,p3z,w3);
0619 
0620       const float* nos = a_nms+3*index;
0621 
0622       n1x = *nos;nos++;
0623       n1y = *nos;nos++;
0624       n1z = *nos;nos++;
0625       project_normal(n1x,n1y,n1z);
0626 
0627       n2x = *nos;nos++;
0628       n2y = *nos;nos++;
0629       n2z = *nos;nos++;
0630       project_normal(n2x,n2y,n2z);
0631 
0632       n3x = *nos;nos++;
0633       n3y = *nos;nos++;
0634       n3z = *nos;nos++;
0635       project_normal(n3x,n3y,n3z);
0636 
0637       if(!add_triangle_normal(p1x,p1y,p1z,w1, n1x,n1y,n1z,
0638                               p2x,p2y,p2z,w2, n2x,n2y,n2z,
0639                               p3x,p3y,p3z,w3, n3x,n3y,n3z)) {
0640         if(a_stop) return false;
0641       }
0642     }
0643     return true;
0644   }
0645 
0646   bool add_triangles_rgba(size_t a_floatn,const float* a_xyzs,const float* a_rgbas,bool a_stop = false){
0647     size_t num = a_floatn/3;
0648     if(num<3) return false;
0649 
0650     m_mode = gl::triangles();
0651 
0652     float p1x,p1y,p1z,w1=1;
0653     float p2x,p2y,p2z,w2=1;
0654     float p3x,p3y,p3z,w3=1;
0655 
0656     float r1,g1,b1,a1;
0657     float r2,g2,b2,a2;
0658     float r3,g3,b3,a3;
0659 
0660     for(size_t index=0;index<num;index+=3) {
0661 
0662       const float* pos = a_xyzs+3*index;
0663 
0664       p1x = *pos;pos++;
0665       p1y = *pos;pos++;
0666       p1z = *pos;pos++;
0667       project(p1x,p1y,p1z,w1);
0668 
0669       p2x = *pos;pos++;
0670       p2y = *pos;pos++;
0671       p2z = *pos;pos++;
0672       project(p2x,p2y,p2z,w2);
0673 
0674       p3x = *pos;pos++;
0675       p3y = *pos;pos++;
0676       p3z = *pos;pos++;
0677       project(p3x,p3y,p3z,w3);
0678 
0679       const float* ros = a_rgbas+4*index;
0680 
0681       r1 = *ros;ros++;
0682       g1 = *ros;ros++;
0683       b1 = *ros;ros++;
0684       a1 = *ros;ros++;
0685 
0686       r2 = *ros;ros++;
0687       g2 = *ros;ros++;
0688       b2 = *ros;ros++;
0689       a2 = *ros;ros++;
0690 
0691       r3 = *ros;ros++;
0692       g3 = *ros;ros++;
0693       b3 = *ros;ros++;
0694       a3 = *ros;ros++;
0695 
0696       if(!add_triangle(p1x,p1y,p1z,w1,r1,g1,b1,a1,
0697                        p2x,p2y,p2z,w2,r2,g2,b2,a2,
0698                        p3x,p3y,p3z,w3,r3,g3,b3,a3)) {
0699         if(a_stop) return false;
0700       }
0701     }
0702     return true;
0703   }
0704 
0705   bool add_triangles_normal_rgba(size_t a_floatn,const float* a_xyzs,const float* a_nms,const float* a_rgbas,bool a_stop = false){
0706     size_t num = a_floatn/3;
0707     if(num<3) return false;
0708 
0709     m_mode = gl::triangles();
0710 
0711     float p1x,p1y,p1z,w1=1;
0712     float p2x,p2y,p2z,w2=1;
0713     float p3x,p3y,p3z,w3=1;
0714 
0715     float n1x,n1y,n1z;
0716     float n2x,n2y,n2z;
0717     float n3x,n3y,n3z;
0718 
0719     float r1,g1,b1,a1;
0720     float r2,g2,b2,a2;
0721     float r3,g3,b3,a3;
0722 
0723     for(size_t index=0;index<num;index+=3) {
0724 
0725       const float* pos = a_xyzs+3*index;
0726 
0727       p1x = *pos;pos++;
0728       p1y = *pos;pos++;
0729       p1z = *pos;pos++;
0730       project(p1x,p1y,p1z,w1);
0731 
0732       p2x = *pos;pos++;
0733       p2y = *pos;pos++;
0734       p2z = *pos;pos++;
0735       project(p2x,p2y,p2z,w2);
0736 
0737       p3x = *pos;pos++;
0738       p3y = *pos;pos++;
0739       p3z = *pos;pos++;
0740       project(p3x,p3y,p3z,w3);
0741 
0742       const float* nos = a_nms+3*index;
0743 
0744       n1x = *nos;nos++;
0745       n1y = *nos;nos++;
0746       n1z = *nos;nos++;
0747       project_normal(n1x,n1y,n1z);
0748 
0749       n2x = *nos;nos++;
0750       n2y = *nos;nos++;
0751       n2z = *nos;nos++;
0752       project_normal(n2x,n2y,n2z);
0753 
0754       n3x = *nos;nos++;
0755       n3y = *nos;nos++;
0756       n3z = *nos;nos++;
0757       project_normal(n3x,n3y,n3z);
0758 
0759       const float* ros = a_rgbas+4*index;
0760 
0761       r1 = *ros;ros++;
0762       g1 = *ros;ros++;
0763       b1 = *ros;ros++;
0764       a1 = *ros;ros++;
0765 
0766       r2 = *ros;ros++;
0767       g2 = *ros;ros++;
0768       b2 = *ros;ros++;
0769       a2 = *ros;ros++;
0770 
0771       r3 = *ros;ros++;
0772       g3 = *ros;ros++;
0773       b3 = *ros;ros++;
0774       a3 = *ros;ros++;
0775 
0776       if(!add_triangle_normal(p1x,p1y,p1z,w1, n1x,n1y,n1z, r1,g1,b1,a1,
0777                               p2x,p2y,p2z,w2, n2x,n2y,n2z, r2,g2,b2,a2,
0778                               p3x,p3y,p3z,w3, n3x,n3y,n3z, r3,g3,b3,a3)) {
0779         if(a_stop) return false;
0780       }
0781     }
0782     return true;
0783   }
0784 
0785   bool add_line_strip(size_t a_floatn,const float* a_xyzs,bool a_stop = false){
0786     size_t num = a_floatn/3;
0787     if(num<=1) return false;
0788     size_t nseg = num-1;
0789 
0790     m_mode = gl::line_strip();
0791 
0792     float xb,yb,zb,wb,xe,ye,ze,we;
0793     float* pos;
0794     for(size_t iseg = 0;iseg<nseg;iseg++) {
0795       pos = (float*)(a_xyzs+3*iseg);
0796       xb = *pos;pos++;
0797       yb = *pos;pos++;
0798       zb = *pos;pos++;
0799       project(xb,yb,zb,wb);
0800 
0801       xe = *pos;pos++;
0802       ye = *pos;pos++;
0803       ze = *pos;pos++;
0804       project(xe,ye,ze,we);
0805 
0806       if(!add_line(xb,yb,zb,wb, xe,ye,ze,we)) {if(a_stop) return false;}
0807     }
0808     return true;
0809   }
0810 
0811   bool add_line_strip_rgba(size_t a_floatn,const float* a_xyzs,const float* a_rgbas,bool a_stop = false){
0812     size_t num = a_floatn/3;
0813     if(num<=1) return false;
0814     size_t nseg = num-1;
0815 
0816     m_mode = gl::line_strip();
0817 
0818     float xb,yb,zb,wb,xe,ye,ze,we;
0819     float rb,gb,bb,ab,re,ge,be,ae;
0820     float* pos;
0821     float* ros;
0822     for(size_t iseg = 0;iseg<nseg;iseg++) {
0823       pos = (float*)(a_xyzs+3*iseg);
0824       xb = *pos;pos++;
0825       yb = *pos;pos++;
0826       zb = *pos;pos++;
0827       project(xb,yb,zb,wb);
0828 
0829       xe = *pos;pos++;
0830       ye = *pos;pos++;
0831       ze = *pos;pos++;
0832       project(xe,ye,ze,we);
0833 
0834       ros = (float*)(a_rgbas+4*iseg);
0835       rb = *ros;ros++;
0836       gb = *ros;ros++;
0837       bb = *ros;ros++;
0838       ab = *ros;ros++;
0839 
0840       re = *ros;ros++;
0841       ge = *ros;ros++;
0842       be = *ros;ros++;
0843       ae = *ros;ros++;
0844 
0845       if(!add_line(xb,yb,zb,wb,rb,gb,bb,ab,
0846                    xe,ye,ze,we,re,ge,be,ae)) {
0847         if(a_stop) return false;
0848       }
0849     }
0850     return true;
0851   }
0852 
0853   bool add_line_strip_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms,bool a_stop = false){
0854     size_t num = a_floatn/3;
0855     if(num<=1) return false;
0856     size_t nseg = num-1;
0857 
0858     m_mode = gl::line_strip();
0859 
0860     float xb,yb,zb,wb,xe,ye,ze,we;
0861     float nxb,nyb,nzb,nxe,nye,nze;
0862     float* pos;
0863     float* nos;
0864     for(size_t iseg = 0;iseg<nseg;iseg++) {
0865       pos = (float*)(a_xyzs+3*iseg);
0866       xb = *pos;pos++;
0867       yb = *pos;pos++;
0868       zb = *pos;pos++;
0869       project(xb,yb,zb,wb);
0870 
0871       xe = *pos;pos++;
0872       ye = *pos;pos++;
0873       ze = *pos;pos++;
0874       project(xe,ye,ze,we);
0875 
0876       nos = (float*)(a_nms+3*iseg);
0877       nxb = *nos;nos++;
0878       nyb = *nos;nos++;
0879       nzb = *nos;nos++;
0880       project_normal(nxb,nyb,nzb);
0881 
0882       nxe = *nos;nos++;
0883       nye = *nos;nos++;
0884       nze = *nos;nos++;
0885       project_normal(nxe,nye,nze);
0886 
0887       if(!add_line_normal(xb,yb,zb,wb, nxb,nyb,nzb,
0888                           xe,ye,ze,we, nxe,nye,nze)) {if(a_stop) return false;}
0889     }
0890     return true;
0891   }
0892 
0893   bool add_line_strip_normal_rgba(size_t a_floatn,const float* a_xyzs,const float* a_nms,const float* a_rgbas,bool a_stop = false){
0894     size_t num = a_floatn/3;
0895     if(num<=1) return false;
0896     size_t nseg = num-1;
0897 
0898     m_mode = gl::line_strip();
0899 
0900     float xb,yb,zb,wb,xe,ye,ze,we;
0901     float nxb,nyb,nzb,nxe,nye,nze;
0902     float rb,gb,bb,ab,re,ge,be,ae;
0903     float* pos;
0904     float* nos;
0905     float* ros;
0906     for(size_t iseg = 0;iseg<nseg;iseg++) {
0907       pos = (float*)(a_xyzs+3*iseg);
0908       xb = *pos;pos++;
0909       yb = *pos;pos++;
0910       zb = *pos;pos++;
0911       project(xb,yb,zb,wb);
0912 
0913       xe = *pos;pos++;
0914       ye = *pos;pos++;
0915       ze = *pos;pos++;
0916       project(xe,ye,ze,we);
0917 
0918       nos = (float*)(a_nms+3*iseg);
0919       nxb = *nos;nos++;
0920       nyb = *nos;nos++;
0921       nzb = *nos;nos++;
0922       project_normal(nxb,nyb,nzb);
0923 
0924       nxe = *nos;nos++;
0925       nye = *nos;nos++;
0926       nze = *nos;nos++;
0927       project_normal(nxe,nye,nze);
0928 
0929       ros = (float*)(a_rgbas+4*iseg);
0930       rb = *ros;ros++;
0931       gb = *ros;ros++;
0932       bb = *ros;ros++;
0933       ab = *ros;ros++;
0934 
0935       re = *ros;ros++;
0936       ge = *ros;ros++;
0937       be = *ros;ros++;
0938       ae = *ros;ros++;
0939 
0940       if(!add_line_normal(xb,yb,zb,wb, nxb,nyb,nzb, rb,gb,bb,ab,
0941                           xe,ye,ze,we, nxe,nye,nze, re,ge,be,ae)) {
0942         if(a_stop) return false;
0943       }
0944     }
0945     return true;
0946   }
0947 
0948   bool add_line_loop(size_t a_floatn,const float* a_xyzs,bool a_stop = false) {
0949     size_t num = a_floatn/3;
0950     if(num<=1) return false;
0951     size_t nseg = num-1;
0952 
0953     m_mode = gl::line_loop();
0954 
0955     float xb,yb,zb,wb,xe,ye,ze,we;
0956     float* pos;
0957     for(size_t iseg = 0;iseg<nseg;iseg++) {
0958       pos = (float*)(a_xyzs+3*iseg);
0959       xb = *pos;pos++;
0960       yb = *pos;pos++;
0961       zb = *pos;pos++;
0962       project(xb,yb,zb,wb);
0963 
0964       xe = *pos;pos++;
0965       ye = *pos;pos++;
0966       ze = *pos;pos++;
0967       project(xe,ye,ze,we);
0968 
0969       if(!add_line(xb,yb,zb,wb, xe,ye,ze,we)) {if(a_stop) return false;}
0970     }
0971 
0972     //close the loop :
0973    {pos = (float*)(a_xyzs+3*(nseg-1)+3);
0974     xb = *pos;pos++;
0975     yb = *pos;pos++;
0976     zb = *pos;pos++;
0977     project(xb,yb,zb,wb);
0978 
0979     pos = (float*)(a_xyzs); //first point.
0980     xe = *pos;pos++;
0981     ye = *pos;pos++;
0982     ze = *pos;pos++;
0983     project(xe,ye,ze,we);
0984 
0985     if(!add_line(xb,yb,zb,wb, xe,ye,ze,we)){if(a_stop) return false;}
0986     }
0987 
0988     return true;
0989   }
0990 
0991   bool add_line_loop_rgba(size_t a_floatn,const float* a_xyzs,const float* a_rgbas,bool a_stop = false) {
0992     size_t num = a_floatn/3;
0993     if(num<=1) return false;
0994     size_t nseg = num-1;
0995 
0996     m_mode = gl::line_loop();
0997 
0998     float xb,yb,zb,wb,xe,ye,ze,we;
0999     float rb,gb,bb,ab,re,ge,be,ae;
1000     float* pos;
1001     float* ros;
1002     for(size_t iseg = 0;iseg<nseg;iseg++) {
1003       pos = (float*)(a_xyzs+3*iseg);
1004       xb = *pos;pos++;
1005       yb = *pos;pos++;
1006       zb = *pos;pos++;
1007       project(xb,yb,zb,wb);
1008 
1009       xe = *pos;pos++;
1010       ye = *pos;pos++;
1011       ze = *pos;pos++;
1012       project(xe,ye,ze,we);
1013 
1014       ros = (float*)(a_rgbas+4*iseg);
1015       rb = *ros;ros++;
1016       gb = *ros;ros++;
1017       bb = *ros;ros++;
1018       ab = *ros;ros++;
1019 
1020       re = *ros;ros++;
1021       ge = *ros;ros++;
1022       be = *ros;ros++;
1023       ae = *ros;ros++;
1024 
1025       if(!add_line(xb,yb,zb,wb,rb,gb,bb,ab,
1026                    xe,ye,ze,we,re,ge,be,ae)) {
1027         if(a_stop) return false;
1028       }
1029     }
1030 
1031     //close the loop :
1032    {pos = (float*)(a_xyzs+3*nseg);
1033     xb = *pos;pos++;
1034     yb = *pos;pos++;
1035     zb = *pos;pos++;
1036     project(xb,yb,zb,wb);
1037 
1038     pos = (float*)(a_xyzs); //first point.
1039     xe = *pos;pos++;
1040     ye = *pos;pos++;
1041     ze = *pos;pos++;
1042     project(xe,ye,ze,we);
1043 
1044     ros = (float*)(a_rgbas+4*nseg);
1045     rb = *ros;ros++;
1046     gb = *ros;ros++;
1047     bb = *ros;ros++;
1048     ab = *ros;ros++;
1049 
1050     ros = (float*)(a_rgbas);
1051     re = *ros;ros++;
1052     ge = *ros;ros++;
1053     be = *ros;ros++;
1054     ae = *ros;ros++;
1055 
1056     if(!add_line(xb,yb,zb,wb,rb,gb,bb,ab,
1057                  xe,ye,ze,we,re,ge,be,ae)){if(a_stop) return false;}
1058     }
1059 
1060     return true;
1061   }
1062 
1063   bool add_line_loop_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms,bool a_stop = false) {
1064     size_t num = a_floatn/3;
1065     if(num<=1) return false;
1066     size_t nseg = num-1;
1067 
1068     m_mode = gl::line_loop();
1069 
1070     float xb,yb,zb,wb,xe,ye,ze,we;
1071     float nxb,nyb,nzb,nxe,nye,nze;
1072     float* pos;
1073     float* nos;
1074     for(size_t iseg = 0;iseg<nseg;iseg++) {
1075       pos = (float*)(a_xyzs+3*iseg);
1076       xb = *pos;pos++;
1077       yb = *pos;pos++;
1078       zb = *pos;pos++;
1079       project(xb,yb,zb,wb);
1080 
1081       xe = *pos;pos++;
1082       ye = *pos;pos++;
1083       ze = *pos;pos++;
1084       project(xe,ye,ze,we);
1085 
1086       nos = (float*)(a_nms+3*iseg);
1087       nxb = *nos;nos++;
1088       nyb = *nos;nos++;
1089       nzb = *nos;nos++;
1090       project_normal(nxb,nyb,nzb);
1091 
1092       nxe = *nos;nos++;
1093       nye = *nos;nos++;
1094       nze = *nos;nos++;
1095       project_normal(nxe,nye,nze);
1096 
1097       if(!add_line_normal(xb,yb,zb,wb, nxb,nyb,nzb,
1098                           xe,ye,ze,we, nxe,nye,nze)) {if(a_stop) return false;}
1099     }
1100 
1101     //close the loop :
1102    {pos = (float*)(a_xyzs+3*(nseg-1)+3);
1103     xb = *pos;pos++;
1104     yb = *pos;pos++;
1105     zb = *pos;pos++;
1106     project(xb,yb,zb,wb);
1107 
1108     pos = (float*)(a_xyzs); //first point.
1109     xe = *pos;pos++;
1110     ye = *pos;pos++;
1111     ze = *pos;pos++;
1112     project(xe,ye,ze,we);
1113 
1114     nos = (float*)(a_nms+3*(nseg-1)+3);
1115     nxb = *nos;nos++;
1116     nyb = *nos;nos++;
1117     nzb = *nos;nos++;
1118     project_normal(nxb,nyb,nzb);
1119 
1120     nos = (float*)(a_nms);
1121     nxe = *nos;nos++;
1122     nye = *nos;nos++;
1123     nze = *nos;nos++;
1124     project_normal(nxe,nye,nze);
1125 
1126     if(!add_line_normal(xb,yb,zb,wb, nxb,nyb,nzb,
1127                         xe,ye,ze,we, nxe,nye,nze)) {if(a_stop) return false;}
1128 
1129     }
1130 
1131     return true;
1132   }
1133 
1134   bool add_line_loop_normal_rgba(size_t a_floatn,const float* a_xyzs,const float* a_nms,const float* a_rgbas,bool a_stop = false) {
1135     size_t num = a_floatn/3;
1136     if(num<=1) return false;
1137     size_t nseg = num-1;
1138 
1139     m_mode = gl::line_loop();
1140 
1141     float xb,yb,zb,wb,xe,ye,ze,we;
1142     float nxb,nyb,nzb,nxe,nye,nze;
1143     float rb,gb,bb,ab,re,ge,be,ae;
1144     float* pos;
1145     float* nos;
1146     float* ros;
1147     for(size_t iseg = 0;iseg<nseg;iseg++) {
1148       pos = (float*)(a_xyzs+3*iseg);
1149       xb = *pos;pos++;
1150       yb = *pos;pos++;
1151       zb = *pos;pos++;
1152       project(xb,yb,zb,wb);
1153 
1154       xe = *pos;pos++;
1155       ye = *pos;pos++;
1156       ze = *pos;pos++;
1157       project(xe,ye,ze,we);
1158 
1159       nos = (float*)(a_nms+3*iseg);
1160       nxb = *nos;nos++;
1161       nyb = *nos;nos++;
1162       nzb = *nos;nos++;
1163       project_normal(nxb,nyb,nzb);
1164 
1165       nxe = *nos;nos++;
1166       nye = *nos;nos++;
1167       nze = *nos;nos++;
1168       project_normal(nxe,nye,nze);
1169 
1170       ros = (float*)(a_rgbas+4*iseg);
1171       rb = *ros;ros++;
1172       gb = *ros;ros++;
1173       bb = *ros;ros++;
1174       ab = *ros;ros++;
1175 
1176       re = *ros;ros++;
1177       ge = *ros;ros++;
1178       be = *ros;ros++;
1179       ae = *ros;ros++;
1180 
1181       if(!add_line_normal(xb,yb,zb,wb, nxb,nyb,nzb, rb,gb,bb,ab,
1182                           xe,ye,ze,we, nxe,nye,nze, re,ge,be,ae)) {
1183         if(a_stop) return false;
1184       }
1185     }
1186 
1187     //close the loop :
1188    {pos = (float*)(a_xyzs+3*nseg);
1189     xb = *pos;pos++;
1190     yb = *pos;pos++;
1191     zb = *pos;pos++;
1192     project(xb,yb,zb,wb);
1193 
1194     pos = (float*)(a_xyzs); //first point.
1195     xe = *pos;pos++;
1196     ye = *pos;pos++;
1197     ze = *pos;pos++;
1198     project(xe,ye,ze,we);
1199 
1200     nos = (float*)(a_nms+3*nseg);
1201     nxb = *nos;nos++;
1202     nyb = *nos;nos++;
1203     nzb = *nos;nos++;
1204     project_normal(nxb,nyb,nzb);
1205 
1206     nos = (float*)(a_nms);
1207     nxe = *nos;nos++;
1208     nye = *nos;nos++;
1209     nze = *nos;nos++;
1210     project_normal(nxe,nye,nze);
1211 
1212     ros = (float*)(a_rgbas+4*nseg);
1213     rb = *ros;ros++;
1214     gb = *ros;ros++;
1215     bb = *ros;ros++;
1216     ab = *ros;ros++;
1217 
1218     ros = (float*)(a_rgbas);
1219     re = *ros;ros++;
1220     ge = *ros;ros++;
1221     be = *ros;ros++;
1222     ae = *ros;ros++;
1223 
1224     if(!add_line_normal(xb,yb,zb,wb, nxb,nyb,nzb, rb,gb,bb,ab,
1225                         xe,ye,ze,we, nxe,nye,nze, re,ge,be,ae)) {
1226       if(a_stop) return false;
1227     }
1228 
1229     }
1230 
1231     return true;
1232   }
1233 
1234   bool add_lines(size_t a_floatn,const float* a_xyzs,bool a_stop = false) {
1235     //lines = segments.
1236     size_t num = a_floatn/3;
1237 
1238     size_t nseg = num/2;
1239     if(!nseg) return false;
1240 
1241     m_mode = gl::lines();
1242 
1243     float xb,yb,zb,wb,xe,ye,ze,we;
1244     float* pos;
1245     for(size_t iseg = 0;iseg<nseg;iseg++) {
1246       pos = (float*)(a_xyzs+6*iseg);
1247       xb = *pos;pos++;
1248       yb = *pos;pos++;
1249       zb = *pos;pos++;
1250       project(xb,yb,zb,wb);
1251 
1252       xe = *pos;pos++;
1253       ye = *pos;pos++;
1254       ze = *pos;pos++;
1255       project(xe,ye,ze,we);
1256 
1257       if(!add_line(xb,yb,zb,wb, xe,ye,ze,we)) {if(a_stop) return false;}
1258     }
1259     return true;
1260   }
1261 
1262   bool add_lines_rgba(size_t a_floatn,const float* a_xyzs,const float* a_rgbas,bool a_stop = false) {
1263     //lines = segments.
1264     size_t num = a_floatn/3;
1265 
1266     size_t nseg = num/2;
1267     if(!nseg) return false;
1268 
1269     m_mode = gl::lines();
1270 
1271     float xb,yb,zb,wb,xe,ye,ze,we;
1272     float rb,gb,bb,ab,re,ge,be,ae;
1273     float* pos;
1274     float* ros;
1275     for(size_t iseg = 0;iseg<nseg;iseg++) {
1276       pos = (float*)(a_xyzs+6*iseg);
1277       xb = *pos;pos++;
1278       yb = *pos;pos++;
1279       zb = *pos;pos++;
1280       project(xb,yb,zb,wb);
1281 
1282       xe = *pos;pos++;
1283       ye = *pos;pos++;
1284       ze = *pos;pos++;
1285       project(xe,ye,ze,we);
1286 
1287       ros = (float*)(a_rgbas+8*iseg);
1288       rb = *ros;ros++;
1289       gb = *ros;ros++;
1290       bb = *ros;ros++;
1291       ab = *ros;ros++;
1292 
1293       re = *ros;ros++;
1294       ge = *ros;ros++;
1295       be = *ros;ros++;
1296       ae = *ros;ros++;
1297 
1298       if(!add_line(xb,yb,zb,wb,rb,gb,bb,ab, xe,ye,ze,we,re,ge,be,ae)) {if(a_stop) return false;}
1299     }
1300     return true;
1301   }
1302 
1303   bool add_lines_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms,bool a_stop = false) {
1304     //lines = segments.
1305     size_t num = a_floatn/3;
1306 
1307     size_t nseg = num/2;
1308     if(!nseg) return false;
1309 
1310     m_mode = gl::lines();
1311 
1312     float xb,yb,zb,wb,xe,ye,ze,we;
1313     float nxb,nyb,nzb,nxe,nye,nze;
1314 
1315     float* pos;
1316     float* nos;
1317 
1318     for(size_t iseg = 0;iseg<nseg;iseg++) {
1319       pos = (float*)(a_xyzs+6*iseg);
1320       xb = *pos;pos++;
1321       yb = *pos;pos++;
1322       zb = *pos;pos++;
1323       project(xb,yb,zb,wb);
1324 
1325       xe = *pos;pos++;
1326       ye = *pos;pos++;
1327       ze = *pos;pos++;
1328       project(xe,ye,ze,we);
1329 
1330       nos = (float*)(a_nms+6*iseg);
1331       nxb = *nos;nos++;
1332       nyb = *nos;nos++;
1333       nzb = *nos;nos++;
1334       project_normal(nxb,nyb,nzb);
1335 
1336       nxe = *nos;nos++;
1337       nye = *nos;nos++;
1338       nze = *nos;nos++;
1339       project_normal(nxe,nye,nze);
1340 
1341       if(!add_line_normal(xb,yb,zb,wb, nxb,nyb,nzb,
1342                           xe,ye,ze,we, nxe,nye,nze)) {if(a_stop) return false;}
1343     }
1344     return true;
1345   }
1346 
1347   bool add_lines_normal_rgba(size_t a_floatn,const float* a_xyzs,const float* a_nms,const float* a_rgbas,bool a_stop = false) {
1348     //lines = segments.
1349     size_t num = a_floatn/3;
1350 
1351     size_t nseg = num/2;
1352     if(!nseg) return false;
1353 
1354     m_mode = gl::lines();
1355 
1356     float xb,yb,zb,wb,xe,ye,ze,we;
1357     float nxb,nyb,nzb,nxe,nye,nze;
1358     float rb,gb,bb,ab,re,ge,be,ae;
1359     float* pos;
1360     float* nos;
1361     float* ros;
1362 
1363     for(size_t iseg = 0;iseg<nseg;iseg++) {
1364       pos = (float*)(a_xyzs+6*iseg);
1365       xb = *pos;pos++;
1366       yb = *pos;pos++;
1367       zb = *pos;pos++;
1368       project(xb,yb,zb,wb);
1369 
1370       xe = *pos;pos++;
1371       ye = *pos;pos++;
1372       ze = *pos;pos++;
1373       project(xe,ye,ze,we);
1374 
1375       nos = (float*)(a_nms+6*iseg);
1376       nxb = *nos;nos++;
1377       nyb = *nos;nos++;
1378       nzb = *nos;nos++;
1379       project_normal(nxb,nyb,nzb);
1380 
1381       nxe = *nos;nos++;
1382       nye = *nos;nos++;
1383       nze = *nos;nos++;
1384       project_normal(nxe,nye,nze);
1385 
1386       ros = (float*)(a_rgbas+8*iseg);
1387       rb = *ros;ros++;
1388       gb = *ros;ros++;
1389       bb = *ros;ros++;
1390       ab = *ros;ros++;
1391 
1392       re = *ros;ros++;
1393       ge = *ros;ros++;
1394       be = *ros;ros++;
1395       ae = *ros;ros++;
1396 
1397       if(!add_line_normal(xb,yb,zb,wb, nxb,nyb,nzb, rb,gb,bb,ab,
1398                           xe,ye,ze,we, nxe,nye,nze, re,ge,be,ae)) {if(a_stop) return false;}
1399     }
1400     return true;
1401   }
1402 
1403   bool add_points(size_t a_floatn,const float* a_xyzs,bool a_stop = false){
1404     size_t num = a_floatn/3;
1405 
1406     m_mode = gl::points();
1407 
1408     float x,y,z,w;
1409     float* pos;
1410     for(size_t ipt=0;ipt<num;ipt++) {
1411       pos = (float*)(a_xyzs+3*ipt);
1412       x = *pos;pos++;
1413       y = *pos;pos++;
1414       z = *pos;pos++;
1415       project(x,y,z,w);
1416 
1417       if(!add_point(x,y,z,w)) {if(a_stop) return false;}
1418     }
1419     return true;
1420   }
1421 
1422   bool add_points_rgba(size_t a_floatn,const float* a_xyzs,const float* a_rgbas,bool a_stop = false){
1423     size_t num = a_floatn/3;
1424 
1425     m_mode = gl::points();
1426 
1427     float x,y,z,w;
1428     float r,g,b,a;
1429 
1430     float* pos;
1431     float* ros;
1432 
1433     for(size_t ipt=0;ipt<num;ipt++) {
1434       pos = (float*)(a_xyzs+3*ipt);
1435       x = *pos;pos++;
1436       y = *pos;pos++;
1437       z = *pos;pos++;
1438       project(x,y,z,w);
1439 
1440       ros = (float*)(a_rgbas+4*ipt);
1441       r = *ros;ros++;
1442       g = *ros;ros++;
1443       b = *ros;ros++;
1444       a = *ros;ros++;
1445 
1446       if(!add_point(x,y,z,w,r,g,b,a)) {if(a_stop) return false;}
1447     }
1448     return true;
1449   }
1450 
1451   bool add_points_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms,bool a_stop = false){
1452     size_t num = a_floatn/3;
1453 
1454     m_mode = gl::points();
1455 
1456     float x,y,z,w;
1457     float nx,ny,nz;
1458     float* pos;
1459     float* nos;
1460 
1461     for(size_t ipt=0;ipt<num;ipt++) {
1462       pos = (float*)(a_xyzs+3*ipt);
1463       x = *pos;pos++;
1464       y = *pos;pos++;
1465       z = *pos;pos++;
1466       project(x,y,z,w);
1467 
1468       nos = (float*)(a_nms+3*ipt);
1469       nx = *nos;nos++;
1470       ny = *nos;nos++;
1471       nz = *nos;nos++;
1472       project_normal(nx,ny,nz);
1473 
1474       if(!add_point_normal(x,y,z,w,nx,ny,nz)) {if(a_stop) return false;}
1475     }
1476     return true;
1477   }
1478 
1479   bool add_points_normal_rgba(size_t a_floatn,const float* a_xyzs,const float* a_nms,const float* a_rgbas,bool a_stop = false){
1480     size_t num = a_floatn/3;
1481 
1482     m_mode = gl::points();
1483 
1484     float x,y,z,w;
1485     float nx,ny,nz;
1486     float r,g,b,a;
1487 
1488     float* pos;
1489     float* nos;
1490     float* ros;
1491 
1492     for(size_t ipt=0;ipt<num;ipt++) {
1493       pos = (float*)(a_xyzs+3*ipt);
1494       x = *pos;pos++;
1495       y = *pos;pos++;
1496       z = *pos;pos++;
1497       project(x,y,z,w);
1498 
1499       nos = (float*)(a_nms+3*ipt);
1500       nx = *nos;nos++;
1501       ny = *nos;nos++;
1502       nz = *nos;nos++;
1503       project_normal(nx,ny,nz);
1504 
1505       ros = (float*)(a_rgbas+4*ipt);
1506       r = *ros;ros++;
1507       g = *ros;ros++;
1508       b = *ros;ros++;
1509       a = *ros;ros++;
1510 
1511       if(!add_point_normal(x,y,z,w,nx,ny,nz,r,g,b,a)) {if(a_stop) return false;}
1512     }
1513     return true;
1514   }
1515 
1516   bool add_primitive(gl::mode_t a_mode,size_t a_floatn,const float* a_xyzs,bool a_stop = false) {
1517 
1518     if(a_mode==gl::points()) {
1519       return add_points(a_floatn,a_xyzs,a_stop);
1520 
1521     } else if(a_mode==gl::lines()) {
1522       return add_lines(a_floatn,a_xyzs,a_stop);
1523 
1524     } else if(a_mode==gl::line_loop()) {
1525       return add_line_loop(a_floatn,a_xyzs,a_stop);
1526 
1527     } else if(a_mode==gl::line_strip()) {
1528       return add_line_strip(a_floatn,a_xyzs,a_stop);
1529 
1530     } else if(a_mode==gl::triangles()) {
1531       return add_triangles(a_floatn,a_xyzs,a_stop);
1532 
1533     } else if(a_mode==gl::triangle_strip()) {
1534       return add_triangle_strip(a_floatn,a_xyzs,a_stop);
1535 
1536     } else if(a_mode==gl::triangle_fan()) {
1537       return add_triangle_fan(a_floatn,a_xyzs,a_stop);
1538 
1539     } else {
1540       return false;
1541     }
1542   }
1543 
1544   bool add_primitive_rgba(gl::mode_t a_mode,size_t a_floatn,const float* a_xyzs,const float* a_rgbas,bool a_stop = false){
1545 
1546     if(a_mode==gl::points()) {
1547       return add_points_rgba(a_floatn,a_xyzs,a_rgbas,a_stop);
1548 
1549     } else if(a_mode==gl::lines()) {
1550       return add_lines_rgba(a_floatn,a_xyzs,a_rgbas,a_stop);
1551 
1552     } else if(a_mode==gl::line_loop()) {
1553       return add_line_loop_rgba(a_floatn,a_xyzs,a_rgbas,a_stop);
1554 
1555     } else if(a_mode==gl::line_strip()) {
1556       return add_line_strip_rgba(a_floatn,a_xyzs,a_rgbas,a_stop);
1557 
1558     } else if(a_mode==gl::triangles()) {
1559       return add_triangles_rgba(a_floatn,a_xyzs,a_rgbas,a_stop);
1560 
1561     } else if(a_mode==gl::triangle_strip()) {
1562     //return add_triangle_strip_rgba(a_floatn,a_xyzs,a_rgbas,a_stop); //uuuuu
1563       return add_triangle_strip(a_floatn,a_xyzs,a_stop);
1564 
1565     } else if(a_mode==gl::triangle_fan()) {
1566     //return add_triangle_fan_rgba(a_floatn,a_xyzs,a_rgbas,a_stop); //uuuuu
1567       return add_triangle_fan(a_floatn,a_xyzs,a_stop);
1568 
1569     } else {
1570       return false;
1571     }
1572   }
1573 
1574   bool add_primitive_normal(gl::mode_t a_mode,size_t a_floatn,const float* a_xyzs,const float* a_nms,bool a_stop = false) {
1575 
1576     if(a_mode==gl::points()) {
1577       return add_points_normal(a_floatn,a_xyzs,a_nms,a_stop);
1578 
1579     } else if(a_mode==gl::lines()) {
1580       return add_lines_normal(a_floatn,a_xyzs,a_nms,a_stop);
1581 
1582     } else if(a_mode==gl::line_loop()) {
1583       return add_line_loop_normal(a_floatn,a_xyzs,a_nms,a_stop);
1584 
1585     } else if(a_mode==gl::line_strip()) {
1586       return add_line_strip_normal(a_floatn,a_xyzs,a_nms,a_stop);
1587 
1588     } else if(a_mode==gl::triangles()) {
1589       return add_triangles_normal(a_floatn,a_xyzs,a_nms,a_stop);
1590 
1591     } else if(a_mode==gl::triangle_strip()) {
1592       return add_triangle_strip_normal(a_floatn,a_xyzs,a_nms,a_stop);
1593 
1594     } else if(a_mode==gl::triangle_fan()) {
1595       return add_triangle_fan_normal(a_floatn,a_xyzs,a_nms,a_stop);
1596 
1597     } else {
1598       return false;
1599     }
1600   }
1601 
1602   bool add_primitive_normal_rgba(gl::mode_t a_mode,size_t a_floatn,const float* a_xyzs,const float* a_nms,const float* a_rgbas,bool a_stop = false){
1603 
1604     if(a_mode==gl::points()) {
1605       return add_points_normal_rgba(a_floatn,a_xyzs,a_nms,a_rgbas,a_stop);
1606 
1607     } else if(a_mode==gl::lines()) {
1608       return add_lines_normal_rgba(a_floatn,a_xyzs,a_nms,a_rgbas,a_stop);
1609 
1610     } else if(a_mode==gl::line_loop()) {
1611       return add_line_loop_normal_rgba(a_floatn,a_xyzs,a_nms,a_rgbas,a_stop);
1612 
1613     } else if(a_mode==gl::line_strip()) {
1614       return add_line_strip_normal_rgba(a_floatn,a_xyzs,a_nms,a_rgbas,a_stop);
1615 
1616     } else if(a_mode==gl::triangles()) {
1617       return add_triangles_normal_rgba(a_floatn,a_xyzs,a_nms,a_rgbas,a_stop);
1618 
1619     } else if(a_mode==gl::triangle_strip()) {
1620       return add_triangle_strip_normal_rgba(a_floatn,a_xyzs,a_nms,a_rgbas,a_stop);
1621 
1622     } else if(a_mode==gl::triangle_fan()) {
1623       return add_triangle_fan_normal_rgba(a_floatn,a_xyzs,a_nms,a_rgbas,a_stop);
1624 
1625     } else {
1626       return false;
1627     }
1628   }
1629 
1630   ////////////////////////////////////////////////////////
1631   /// points with x,y only ///////////////////////////////
1632   ////////////////////////////////////////////////////////
1633 
1634   bool add_points_xy(size_t a_floatn,const float* a_xys,bool a_stop = false) {
1635     size_t num = a_floatn/2;
1636 
1637     m_mode = gl::points();
1638 
1639     float x,y,z,w;
1640     float* pos;
1641     for(size_t ipt=0;ipt<num;ipt++) {
1642       pos = (float*)(a_xys+2*ipt);
1643       x = *pos;pos++;
1644       y = *pos;pos++;
1645       z = 0;
1646 
1647       project(x,y,z,w);
1648 
1649       if(!add_point(x,y,z,w)) {if(a_stop) return false;}
1650     }
1651     return true;
1652   }
1653 
1654   bool add_triangle_fan_xy(size_t a_floatn,const float* a_xys,
1655                            bool a_stop = false,
1656                            bool a_triangle_revert = false){
1657     size_t num = a_floatn/2;
1658     if(num<3) return false;
1659 
1660     m_mode = gl::triangle_fan();
1661 
1662     float p1x,p1y,p1z,w1=1;
1663     float p2x,p2y,p2z,w2=1;
1664     float p3x,p3y,p3z,w3=1;
1665 
1666     const float* pos1 = a_xys+2*0;
1667     p1x = *(pos1+0);
1668     p1y = *(pos1+1);
1669     p1z = 0;
1670     project(p1x,p1y,p1z,w1);
1671 
1672     const float* pos2 = a_xys+2*1;
1673     p2x = *(pos2+0);
1674     p2y = *(pos2+1);
1675     p2z = 0;
1676     project(p2x,p2y,p2z,w2);
1677 
1678     for(size_t index=2;index<num;index++) {
1679       const float* pos = a_xys+2*index;
1680       p3x = *(pos+0);
1681       p3y = *(pos+1);
1682       p3z = 0;
1683       project(p3x,p3y,p3z,w3);
1684 
1685       if(a_triangle_revert) {
1686         if(!add_triangle(p3x,p3y,p3z,w3,
1687                          p2x,p2y,p2z,w2,
1688                          p1x,p1y,p1z,w1)) {
1689           if(a_stop) return false;
1690         }
1691       } else {
1692         if(!add_triangle(p1x,p1y,p1z,w1,
1693                          p2x,p2y,p2z,w2,
1694                          p3x,p3y,p3z,w3)) {
1695           if(a_stop) return false;
1696         }
1697       }
1698 
1699 
1700       p2x = p3x;
1701       p2y = p3y;
1702       p2z = p3z;
1703       w2 = w3;
1704     }
1705     return true;
1706   }
1707 
1708   bool add_triangle_strip_xy(size_t a_floatn,const float* a_xys,
1709                              bool a_stop = false,
1710                              bool a_triangle_revert = false){
1711     size_t num = a_floatn/2;
1712     if(num<3) return false;
1713 
1714     m_mode = gl::triangle_strip();
1715 
1716     float p1x,p1y,p1z,w1=1;
1717     float p2x,p2y,p2z,w2=1;
1718     float p3x,p3y,p3z,w3=1;
1719 
1720     const float* pos1 = a_xys+2*0;
1721     p1x = *(pos1+0);
1722     p1y = *(pos1+1);
1723     p1z = 0;
1724     project(p1x,p1y,p1z,w1);
1725 
1726     const float* pos2 = a_xys+2*1;
1727     p2x = *(pos2+0);
1728     p2y = *(pos2+1);
1729     p2z = 0;
1730     project(p2x,p2y,p2z,w2);
1731 
1732     bool flip = false;
1733     for(size_t index=2;index<num;index++) {
1734       const float* pos = a_xys+2*index;
1735       p3x = *(pos+0);
1736       p3y = *(pos+1);
1737       p3z = 0;
1738       project(p3x,p3y,p3z,w3);
1739 
1740       if(a_triangle_revert) {
1741 
1742         if(flip){
1743           if(!add_triangle(p2x,p2y,p2z,w2,
1744                            p3x,p3y,p3z,w3,
1745                            p1x,p1y,p1z,w1)) {
1746             if(a_stop) return false;
1747           }
1748         } else {
1749           if(!add_triangle(p3x,p3y,p3z,w3,
1750                            p2x,p2y,p2z,w2,
1751                            p1x,p1y,p1z,w1)) {
1752             if(a_stop) return false;
1753           }
1754         }
1755 
1756       } else {
1757 
1758         if(flip){
1759           if(!add_triangle(p1x,p1y,p1z,w1,
1760                            p3x,p3y,p3z,w3,
1761                            p2x,p2y,p2z,w2)) {
1762             if(a_stop) return false;
1763           }
1764         } else {
1765           if(!add_triangle(p1x,p1y,p1z,w1,
1766                            p2x,p2y,p2z,w2,
1767                            p3x,p3y,p3z,w3)) {
1768             if(a_stop) return false;
1769           }
1770         }
1771 
1772       }
1773 
1774       p1x = p2x;
1775       p1y = p2y;
1776       p1z = p2z;
1777       w1 = w2;
1778 
1779       p2x = p3x;
1780       p2y = p3y;
1781       p2z = p3z;
1782       w2 = w3;
1783 
1784       flip = flip?false:true;
1785     }
1786     return true;
1787   }
1788 
1789   bool add_triangles_xy(size_t a_floatn,const float* a_xys,bool a_stop = false,bool a_triangle_revert = false){
1790     size_t num = a_floatn/2;
1791     if(num<3) return false;
1792 
1793     m_mode = gl::triangles();
1794 
1795     float p1x,p1y,p1z,w1=1;
1796     float p2x,p2y,p2z,w2=1;
1797     float p3x,p3y,p3z,w3=1;
1798 
1799     for(size_t index=0;index<num;index+=3) {
1800 
1801       const float* pos1 = a_xys+2*index;
1802       p1x = *(pos1+0);
1803       p1y = *(pos1+1);
1804       p1z = 0;
1805       project(p1x,p1y,p1z,w1);
1806 
1807       const float* pos2 = a_xys+2*(index+1);
1808       p2x = *(pos2+0);
1809       p2y = *(pos2+1);
1810       p2z = 0;
1811       project(p2x,p2y,p2z,w2);
1812 
1813       const float* pos3 = a_xys+2*(index+2);
1814       p3x = *(pos3+0);
1815       p3y = *(pos3+1);
1816       p3z = 0;
1817       project(p3x,p3y,p3z,w3);
1818 
1819       if(a_triangle_revert) {
1820         if(!add_triangle(p3x,p3y,p3z,w3,
1821                          p2x,p2y,p2z,w2,
1822                          p1x,p1y,p1z,w1)) {
1823           if(a_stop) return false;
1824         }
1825       } else {
1826         if(!add_triangle(p1x,p1y,p1z,w1,
1827                          p2x,p2y,p2z,w2,
1828                          p3x,p3y,p3z,w3)) {
1829           if(a_stop) return false;
1830         }
1831       }
1832     }
1833     return true;
1834   }
1835 
1836   bool add_line_loop_xy(size_t a_floatn,const float* a_xys,bool a_stop = false){
1837     size_t num = a_floatn/2;
1838     if(num<=1) return false;
1839     size_t nseg = num-1;
1840 
1841     m_mode = gl::line_loop();
1842 
1843     float xb,yb,zb,wb,xe,ye,ze,we;
1844     float* pos;
1845     for(size_t iseg = 0;iseg<nseg;iseg++) {
1846       pos = (float*)(a_xys+2*iseg);
1847       xb = *pos;pos++;
1848       yb = *pos;pos++;
1849       zb = 0;
1850       project(xb,yb,zb,wb);
1851 
1852       xe = *pos;pos++;
1853       ye = *pos;pos++;
1854       ze = 0;
1855       project(xe,ye,ze,we);
1856 
1857       if(!add_line(xb,yb,zb,wb, xe,ye,ze,we)) {if(a_stop) return false;}
1858     }
1859 
1860     //close the loop :
1861    {pos = (float*)(a_xys+2*(nseg-1)+2);
1862     xb = *pos;pos++;
1863     yb = *pos;pos++;
1864     zb = 0;
1865     project(xb,yb,zb,wb);
1866 
1867     pos = (float*)(a_xys); //first point.
1868     xe = *pos;pos++;
1869     ye = *pos;pos++;
1870     ze = 0;
1871     project(xe,ye,ze,we);
1872 
1873     if(!add_line(xb,yb,zb,wb, xe,ye,ze,we)){if(a_stop) return false;}
1874     }
1875 
1876     return true;
1877   }
1878 
1879   bool add_line_strip_xy(size_t a_floatn,const float* a_xys,bool a_stop = false){
1880     size_t num = a_floatn/2;
1881     if(num<=1) return false;
1882     size_t nseg = num-1;
1883 
1884     m_mode = gl::line_strip();
1885 
1886     float xb,yb,zb,wb,xe,ye,ze,we;
1887     float* pos;
1888     for(size_t iseg = 0;iseg<nseg;iseg++) {
1889       pos = (float*)(a_xys+2*iseg);
1890       xb = *pos;pos++;
1891       yb = *pos;pos++;
1892       zb = 0;
1893       project(xb,yb,zb,wb);
1894 
1895       xe = *pos;pos++;
1896       ye = *pos;pos++;
1897       ze = 0;
1898       project(xe,ye,ze,we);
1899 
1900       if(!add_line(xb,yb,zb,wb, xe,ye,ze,we)) {if(a_stop) return false;}
1901     }
1902     return true;
1903   }
1904 
1905   bool add_lines_xy(size_t a_floatn,const float* a_xys,bool a_stop = false){
1906     //lines = segments.  Each point having only (x,y) (no z).
1907     //used in tools::sg::[text_freetype, text_hershey].
1908 
1909     size_t num = a_floatn/2;
1910 
1911     size_t nseg = num/2;
1912     if(!nseg) return false;
1913 
1914     m_mode = gl::lines();
1915 
1916     float xb,yb,zb,wb,xe,ye,ze,we;
1917     float* pos;
1918     for(size_t iseg = 0;iseg<nseg;iseg++) {
1919       pos = (float*)(a_xys+4*iseg);
1920       xb = *pos;pos++;
1921       yb = *pos;pos++;
1922       zb = 0;
1923       project(xb,yb,zb,wb);
1924 
1925       xe = *pos;pos++;
1926       ye = *pos;pos++;
1927       ze = 0;
1928       project(xe,ye,ze,we);
1929 
1930       if(!add_line(xb,yb,zb,wb, xe,ye,ze,we)) {if(a_stop) return false;}
1931     }
1932     return true;
1933   }
1934 
1935   bool add_primitive_xy(gl::mode_t a_mode,size_t a_floatn,const float* a_xys,bool a_stop = false,bool a_triangle_revert = false){
1936 
1937     if(a_mode==gl::points()) {
1938       return add_points_xy(a_floatn,a_xys,a_stop);
1939 
1940     } else if(a_mode==gl::lines()) {
1941       return add_lines_xy(a_floatn,a_xys,a_stop);
1942 
1943     } else if(a_mode==gl::line_loop()) {
1944       return add_line_loop_xy(a_floatn,a_xys,a_stop);
1945 
1946     } else if(a_mode==gl::line_strip()) {
1947       return add_line_strip_xy(a_floatn,a_xys,a_stop);
1948 
1949     } else if(a_mode==gl::triangles()) {
1950       return add_triangles_xy(a_floatn,a_xys,a_stop,a_triangle_revert);
1951 
1952     } else if(a_mode==gl::triangle_strip()) {
1953       return add_triangle_strip_xy(a_floatn,a_xys,a_stop,a_triangle_revert);
1954 
1955     } else if(a_mode==gl::triangle_fan()) {
1956       return add_triangle_fan_xy(a_floatn,a_xys,a_stop,a_triangle_revert);
1957 
1958     } else {
1959       return false;
1960     }
1961   }
1962 
1963 public:
1964   bool add_primitive(gl::mode_t a_mode,const std::vector<float>& a_xyzs,bool a_stop = false){
1965     const float* _xyzs = a_xyzs.data();
1966     return add_primitive(a_mode,a_xyzs.size(),_xyzs,a_stop);
1967   }
1968   bool add_primitive_xy(gl::mode_t a_mode,const std::vector<float>& a_xys,bool a_stop = false,bool a_triangle_revert = false){
1969     const float* _xys = a_xys.data();
1970     return add_primitive_xy(a_mode,a_xys.size(),_xys,a_stop,a_triangle_revert);
1971   }
1972   bool add_line_strip(const std::vector<float>& a_xyzs,bool a_stop = false){
1973     const float* _xyzs = a_xyzs.data();
1974     return add_line_strip(a_xyzs.size(),_xyzs,a_stop);
1975   }
1976   bool add_line_loop(const std::vector<float>& a_xyzs,bool a_stop = false){
1977     const float* _xyzs = a_xyzs.data();
1978     return add_line_loop(a_xyzs.size(),_xyzs,a_stop);
1979   }
1980   bool add_lines(const std::vector<float>& a_xyzs,bool a_stop = false){
1981     const float* _xyzs = a_xyzs.data();
1982     return add_lines(a_xyzs.size(),_xyzs,a_stop);
1983   }
1984   bool add_points(const std::vector<float>& a_xyzs,bool a_stop = false){
1985     const float* _xyzs = a_xyzs.data();
1986     return add_points(a_xyzs.size(),_xyzs,a_stop);
1987   }
1988 
1989   bool add_triangle_strip(const std::vector<float>& a_xyzs,bool a_stop = false){
1990     const float* _xyzs = a_xyzs.data();
1991     return add_triangle_strip(a_xyzs.size(),_xyzs,a_stop);
1992   }
1993 
1994   bool add_points_xy(const std::vector<float>& a_xys,bool a_stop = false){
1995     const float* _xys = a_xys.data();
1996     return add_points_xy(a_xys.size(),_xys,a_stop);
1997   }
1998   bool add_lines_xy(const std::vector<float>& a_xys,bool a_stop = false){
1999     const float* _xys = a_xys.data();
2000     return add_lines_xy(a_xys.size(),_xys,a_stop);
2001   }
2002   bool add_triangle_strip_xy(const std::vector<float>& a_xys,bool a_stop = false){
2003     const float* _xys = a_xys.data();
2004     return add_triangle_strip_xy(a_xys.size(),_xys,a_stop);
2005   }
2006 
2007 
2008 public:
2009   bool add_triangle_fan_texture_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms,unsigned int,const float*){
2010     return add_triangle_fan_normal(a_floatn,a_xyzs,a_nms,false);
2011   }
2012   bool add_triangle_strip_texture_normal(size_t a_floatn,const float* a_xyzs,const float* a_nms,unsigned int,const float*){
2013     return add_triangle_strip_normal(a_floatn,a_xyzs,a_nms,false);
2014   }
2015 
2016   bool add_triangle_strip_as_triangles(size_t a_floatn,const float* a_xyzs,const float* a_nms) { //used in sg::sphere, icosahedron_sphere.
2017     return add_triangle_strip_normal(a_floatn,a_xyzs,a_nms,false); //already do a per triangle treatement.
2018   }
2019 public:
2020   void add_texture(std::ostream& a_out,size_t a_xyzn,const float* a_xyzs,const img_byte& a_img,const float* a_tcs) {
2021     if(a_img.is_empty()) return;
2022 
2023     unsigned int imw = a_img.width();
2024     unsigned int imh = a_img.height();
2025     unsigned int imn = a_img.bytes_per_pixel();
2026     if((imn!=3)&&(imn!=4)) {
2027       a_out << "tools::sg::primitive_visitor::add_texture :"
2028             << " not a 3 or 4 bytes per pixel image."
2029             << std::endl;
2030       return;
2031     }
2032 
2033     if(a_xyzn!=12) {
2034       a_out << "tools::sg::primitive_visitor::add_texture :"
2035             << " primitive has not four points."
2036             << std::endl;
2037       return;
2038     }
2039 
2040     vec3f p1(a_xyzs[0],a_xyzs[ 1],a_xyzs[ 2]);
2041     vec3f p2(a_xyzs[3],a_xyzs[ 4],a_xyzs[ 5]);
2042     vec3f p4(a_xyzs[9],a_xyzs[10],a_xyzs[11]);
2043 
2044     vec3f dx = p2-p1;
2045     vec3f dy = p4-p1;
2046 
2047     vec2f t1(a_tcs[0],a_tcs[1]);
2048     vec2f t2(a_tcs[2],a_tcs[3]);
2049     vec2f t3(a_tcs[4],a_tcs[5]);
2050     vec2f t4(a_tcs[6],a_tcs[7]);
2051     vec2f tdx = t2-t1;
2052     vec2f tdy = t4-t1;
2053     if(!tdx.length()) {
2054       a_out << "tools::sg::primitive_visitor::add_texture :"
2055             << " tdx is null."
2056             << std::endl;
2057       return;
2058     }
2059     if(!tdy.length()) {
2060       a_out << "tools::sg::primitive_visitor::add_texture :"
2061             << " tdy is null."
2062             << std::endl;
2063       return;
2064     }
2065     std::vector<vec2f> poly;
2066     poly.push_back(t1);
2067     poly.push_back(t2);
2068     poly.push_back(t3);
2069     poly.push_back(t4);
2070     poly.push_back(t1);
2071 
2072    {float r,g,b,a,tx,ty;
2073     vec3f p;
2074     vec2f t;
2075     unsigned char* pos = (unsigned char*)a_img.buffer();
2076     for(unsigned int row=0;row<imh;row++) {
2077       for(unsigned int col=0;col<imw;col++) {
2078         r = (*pos)/255.0f;pos++;
2079         g = (*pos)/255.0f;pos++;
2080         b = (*pos)/255.0f;pos++;
2081         a = 1;
2082         if(imn==4) {
2083           a = (*pos)/255.0f;pos++;
2084         }
2085 
2086         tx = float(col)/float(imw-1); //[0,1]
2087         ty = float(row)/float(imh-1); //[0,1]
2088 
2089         t.set_value(tx,ty);
2090 
2091         if(!is_inside(t,poly)) continue;
2092 
2093         t = t - t1;
2094 
2095         p = p1+dx*t.x()/tdx.length()+dy*t.y()/tdy.length();
2096 
2097         add_one_point(p.x(),p.y(),p.z(),r,g,b,a);
2098       }
2099     }}
2100 
2101   }
2102 protected:
2103   gl::mode_t m_mode;
2104 };
2105 
2106 }}
2107 
2108 #endif