46 #include "Primitive.h" 
   47 #include "SortMethod.h" 
   53 double EGALITY_EPS      = 0.0001;
 
   54 double LINE_EGALITY_EPS = 0.0001;
 
   56 typedef enum { BSP_CROSS_PLANE, BSP_UPPER, BSP_LOWER } BSPPosition;
 
   70         void recursFillPrimitiveArray(vector<PtrPrimitive>&) 
const;
 
   73         vector<Segment *> _segments;    
 
   74         vector<Point *> _points;
 
   77 void BSPSortMethod::sortPrimitives(std::vector<PtrPrimitive>& primitive_tab,
VRenderParams& vparams)
 
   84         unsigned int N = primitive_tab.size()/200 +1;
 
   87     vector<PtrPrimitive> segments_and_points;   
 
   89     for(
unsigned int i=0;i<primitive_tab.size();++i,++nbinserted)
 
   91         if((P = dynamic_cast<Polygone *>(primitive_tab[i])) != NULL)
 
   94             segments_and_points.push_back(primitive_tab[i]);
 
   97             vparams.progress(nbinserted/(
float)primitive_tab.size(), QGLViewer::tr(
"BSP Construction"));
 
  105     for(
unsigned int j=0;j<segments_and_points.size();++j,++nbinserted)
 
  107         if((S = dynamic_cast<Segment *>(segments_and_points[j])) != NULL)
 
  109         else if((p = dynamic_cast<Point *>(segments_and_points[j])) != NULL)
 
  113             vparams.progress(nbinserted/(
float)primitive_tab.size(), QGLViewer::tr(
"BSP Construction"));
 
  118     primitive_tab.resize(0);
 
  119     tree.recursFillPrimitiveArray(primitive_tab);
 
  130         void recursFillPrimitiveArray(vector<PtrPrimitive>&) 
const;
 
  134         void insert(
Point *);
 
  142         vector<Segment *> seg_plus;
 
  143         vector<Segment *> seg_moins;
 
  145         vector<Point *> pts_plus;
 
  146         vector<Point *> pts_moins;
 
  152         int  Classify(
Point *);
 
  154         void initEquation(
const Polygone *P,
double & a, 
double & b, 
double & c, 
double & d);
 
  167 void BSPTree::insert(
Point *P)  { 
if(_root == NULL) _points.push_back(P)    ; 
else _root->insert(P); }
 
  168 void BSPTree::insert(
Segment *S) { 
if(_root == NULL) _segments.push_back(S); 
else _root->insert(S); }
 
  169 void BSPTree::insert(
Polygone *P){ 
if(_root == NULL) _root = 
new BSPNode(P); 
else _root->insert(P); }
 
  171 void BSPTree::recursFillPrimitiveArray(vector<PtrPrimitive>& tab)
 const 
  173     if(_root != NULL) _root->recursFillPrimitiveArray(tab);
 
  175     for(
unsigned int i=0;i<_points.size();++i) tab.push_back(_points[i]);
 
  176     for(
unsigned int j=0;j<_segments.size();++j) tab.push_back(_segments[j]);
 
  187 int BSPNode::Classify(
Point *P)
 
  189   double Z = P->sommet3DColor(0).x() * a + P->sommet3DColor(0).y() * b + P->sommet3DColor(0).z() * c - d;
 
  199     double Z1 = S->sommet3DColor(0).x() * a + S->sommet3DColor(0).y() * b + S->sommet3DColor(0).z() * c - d;
 
  200     double Z2 = S->sommet3DColor(1).x() * a + S->sommet3DColor(1).y() * b + S->sommet3DColor(1).z() * c - d;
 
  204     if(Z1 < -LINE_EGALITY_EPS)
 
  206     else if(Z1 > EGALITY_EPS)
 
  211     if(Z2 < -LINE_EGALITY_EPS)
 
  213     else if(Z2 > EGALITY_EPS)
 
  228             double t = fabs(Z1/(Z2 - Z1));
 
  230             if((t < 0.0)||(t > 1.0))
 
  232                 if(t > 1.0) t = 0.999;
 
  233                 if(t < 0.0) t = 0.001;
 
  236             Feedback3DColor newVertex((1-t)*S->sommet3DColor(0) + t*S->sommet3DColor(1));
 
  240                 plus_  = 
new Segment(S->sommet3DColor(0), newVertex);
 
  241                 moins_ = 
new Segment(newVertex, S->sommet3DColor(1));
 
  245                 plus_  = 
new Segment(newVertex, S->sommet3DColor(1));
 
  246                 moins_ = 
new Segment(S->sommet3DColor(0), newVertex);
 
  304     static int Signs[100];
 
  305     static double Zvals[100];
 
  316     int n = P->nbVertices();
 
  325         double Z = P->vertex(i).x() * a + P->vertex(i).y() * b + P->vertex(i).z() * c - d;
 
  329         else if(Z > EGALITY_EPS)
 
  336         if(Smin > Signs[i]) Smin = Signs[i];
 
  337         if(Smax < Signs[i]) Smax = Signs[i];
 
  342     if((Smin == 0)&&(Smax == 0))
 
  367     if((Smin == -1)&&(Smax == 0))
 
  374     if((Smin == 0)&&(Smax == 1))
 
  383     vector<Feedback3DColor> Ps;
 
  384     vector<Feedback3DColor> Ms;
 
  397             if(Signs[(j+1)%n] == 0)
 
  402     if((nZero > 2)||(nconsZero > 0))
 
  413     while(Signs[dep] == 0) dep++;
 
  415     int prev_sign = Signs[dep];
 
  417     for(
int k=1;k<=n;k++)
 
  419         int sign = Signs[(k+dep)%n];
 
  421         if(sign == prev_sign)
 
  424                 Ps.push_back(P->sommet3DColor(k+dep));
 
  427                 Ms.push_back(P->sommet3DColor(k+dep));
 
  429         else if(sign == -prev_sign)
 
  434             double Z1 = Zvals[(k+dep-1)%n];
 
  435             double Z2 = Zvals[(k+dep)%n];
 
  437             double t = fabs(Z1/(Z2 - Z1));
 
  439             if((t < 0.0)||(t > 1.0))
 
  441                 if(t > 1.0) t = 0.999;
 
  442                 if(t < 0.0) t = 0.001;
 
  445             Feedback3DColor newVertex((1-t)*P->sommet3DColor(k+dep-1) + t*P->sommet3DColor(k+dep));
 
  447             Ps.push_back(newVertex);
 
  448             Ms.push_back(newVertex);
 
  451                 Ps.push_back(P->sommet3DColor(k+dep));
 
  454                 Ms.push_back(P->sommet3DColor(k+dep));
 
  462             Ps.push_back(newVertex);
 
  463             Ms.push_back(newVertex);
 
  465             prev_sign = -prev_sign;
 
  491     Polygone *side_plus = NULL, *side_moins = NULL;
 
  495     Classify(P,side_moins,side_plus);
 
  499     if(side_plus != NULL) {
 
  500         if(fils_plus == NULL)
 
  501             fils_plus = 
new BSPNode(side_plus);
 
  503             fils_plus->insert(side_plus);
 
  506     if(side_moins != NULL) {
 
  507         if(fils_moins == NULL)
 
  508             fils_moins = 
new BSPNode(side_moins);
 
  510             fils_moins->insert(side_moins);
 
  514 void BSPNode::recursFillPrimitiveArray(vector<PtrPrimitive>& primitive_tab)
 const 
  516   if(fils_plus != NULL)
 
  517     fils_plus->recursFillPrimitiveArray(primitive_tab);
 
  519   for(
unsigned int i=0;i<seg_plus.size();++i)
 
  520     primitive_tab.push_back(seg_plus[i]);
 
  521   for(
unsigned int j=0;j<pts_plus.size();++j)
 
  522     primitive_tab.push_back(pts_plus[j]);
 
  525     primitive_tab.push_back(polygone);
 
  527   if(fils_moins != NULL)
 
  528     fils_moins->recursFillPrimitiveArray(primitive_tab);
 
  530   for(
unsigned int i2=0;i2<seg_moins.size();++i2)
 
  531     primitive_tab.push_back(seg_moins[i2]);
 
  532   for(
unsigned int j2=0;j2<pts_moins.size();++j2)
 
  533     primitive_tab.push_back(pts_moins[j2]);
 
  536 void BSPNode::insert(
Point *P)
 
  538     int res = Classify(P);
 
  541         if(fils_moins == NULL)
 
  542             pts_moins.push_back(P);
 
  544             fils_moins->insert(P);
 
  548         if(fils_plus == NULL)
 
  549             pts_plus.push_back(P);
 
  551             fils_plus->insert(P);
 
  555 void BSPNode::insert(
Segment *S)
 
  557     Segment *side_plus = NULL, *side_moins = NULL;
 
  559     Classify(S,side_moins,side_plus);
 
  561     if(side_plus != NULL) {
 
  562         if(fils_plus == NULL)
 
  563             seg_plus.push_back(side_plus);
 
  565             fils_plus->insert(side_plus);
 
  568     if(side_moins != NULL) {
 
  569         if(fils_moins == NULL)
 
  570             seg_moins.push_back(side_moins);
 
  572             fils_moins->insert(side_moins);
 
  580   initEquation(P,a,b,c,d);
 
  586 void BSPNode::initEquation(
const Polygone *P,
double & a, 
double & b, 
double & c, 
double & d)
 
  591     while((j < P->nbVertices())&& n.infNorm() <= 0.00001)
 
  593         n = (P->vertex(j+2) - P->vertex(j+1))^(P->vertex(j) - P->vertex(j+1));
 
  597     if(n.infNorm() <= 0.00001)
 
  599                 unsigned int ind = P->nbVertices();
 
  601                 for(
unsigned int i=0;i<P->nbVertices();i++)
 
  602             if((P->vertex(i+1)-P->vertex(i)).infNorm() > 0.00001)
 
  608         if(ind < P->nbVertices())   
 
  610             if((P->vertex(ind+1).x() != P->vertex(ind).x())||(P->vertex(ind+1).y() != P->vertex(ind).y()))
 
  612                 n[0] = - P->vertex(ind+1).y() + P->vertex(ind).y();
 
  613                 n[1] =   P->vertex(ind+1).x() - P->vertex(ind).x();
 
  618                 n[0] = - P->vertex(ind+1).z() + P->vertex(ind).z();
 
  620                 n[2] =   P->vertex(ind+1).x() - P->vertex(ind).x();