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