ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

slicer.cc
Go to the documentation of this file.
00001 /*
00002 ** License Applicability. Except to the extent portions of this file are
00003 ** made subject to an alternative license as permitted in the SGI Free
00004 ** Software License B, Version 1.1 (the "License"), the contents of this
00005 ** file are subject only to the provisions of the License. You may not use
00006 ** this file except in compliance with the License. You may obtain a copy
00007 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
00008 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
00009 **
00010 ** http://oss.sgi.com/projects/FreeB
00011 **
00012 ** Note that, as provided in the License, the Software is distributed on an
00013 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
00014 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
00015 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
00016 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
00017 **
00018 ** Original Code. The Original Code is: OpenGL Sample Implementation,
00019 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
00020 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
00021 ** Copyright in any portions created by third parties is as indicated
00022 ** elsewhere herein. All Rights Reserved.
00023 **
00024 ** Additional Notice Provisions: The application programming interfaces
00025 ** established by SGI in conjunction with the Original Code are The
00026 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
00027 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
00028 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
00029 ** Window System(R) (Version 1.3), released October 19, 1998. This software
00030 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
00031 ** published by SGI, but has not been independently verified as being
00032 ** compliant with the OpenGL(R) version 1.2.1 Specification.
00033 */
00034 
00035 /*
00036  * slicer.c++
00037  *
00038  * $Date: 2006-03-12 00:07:02 +0000 (Sun, 12 Mar 2006) $ $Revision: 1.1 $
00039  * $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libnurbs/internals/slicer.cc,v 1.1 2004/02/02 16:39:12 navaraf Exp $
00040  */
00041 
00042 #include <stdlib.h>
00043 #include <stdio.h>
00044 #include <math.h>
00045 #include "glimports.h"
00046 #include "mystdio.h"
00047 #include "myassert.h"
00048 #include "bufpool.h"
00049 #include "slicer.h"
00050 #include "backend.h"
00051 #include "arc.h"
00052 #include "gridtrimvertex.h"
00053 #include "simplemath.h"
00054 #include "trimvertex.h"
00055 #include "varray.h"
00056 
00057 #include "polyUtil.h" //for area()
00058 
00059 //static int count=0;
00060 
00061 /*USE_OPTTT is initiated in trimvertex.h*/
00062 
00063 #ifdef USE_OPTTT
00064     #include <GL/gl.h>
00065 #endif
00066 
00067 //#define USE_READ_FLAG //whether to use new or old tesselator
00068                           //if defined, it reads "flagFile", 
00069                           // if the number is 1, then use new tess
00070                           // otherwise, use the old tess.
00071                          //if not defined, then use new tess.
00072 #ifdef USE_READ_FLAG
00073 static Int read_flag(char* name);
00074 Int newtess_flag = read_flag("flagFile");
00075 #endif
00076 
00077 //#define COUNT_TRIANGLES
00078 #ifdef COUNT_TRIANGLES
00079 Int num_triangles = 0;
00080 Int num_quads = 0;
00081 #endif
00082 
00083 #define max(a,b) ((a>b)? a:b)
00084 #define ZERO 0.00001 /*determing whether a loop is a rectngle or not*/
00085 #define equalRect(a,b) ((glu_abs(a-b) <= ZERO)? 1:0) //only used in tessellating a rectangle
00086 
00087 /******triangulate a monotone polygon**************/
00088 #include "monoTriangulation.h"
00089 
00090 inline int compInY(REAL a[2], REAL b[2])
00091 {
00092   if(a[1] < b[1])
00093     return -1;
00094   else if (a[1] > b[1])
00095     return 1;
00096   else if(a[0] > b[0])
00097     return 1;
00098   else return -1;
00099 }
00100 
00101 void monoTriangulationLoop(Arc_ptr loop, Backend& backend, primStream* pStream)
00102 {
00103   int i;
00104   //find the top, bottom, increasing and decreasing chain
00105   //then call monoTrianulation
00106   Arc_ptr jarc, temp;
00107   Arc_ptr top;
00108   Arc_ptr bot;
00109   top = bot = loop;
00110   if(compInY(loop->tail(), loop->prev->tail()) < 0)
00111     {
00112       //first find bot
00113       for(temp = loop->next; temp != loop; temp = temp->next)
00114     {
00115       if(compInY(temp->tail(), temp->prev->tail()) > 0)
00116         break;
00117     }
00118       bot = temp->prev;
00119       //then find top
00120       for(temp=loop->prev; temp != loop; temp = temp->prev)
00121     {
00122       if(compInY(temp->tail(), temp->prev->tail()) > 0)
00123         break;
00124     }
00125       top = temp;
00126     }
00127   else //loop > loop->prev
00128     {
00129       for(temp=loop->next; temp != loop; temp = temp->next)
00130     {
00131       if(compInY(temp->tail(), temp->prev->tail()) < 0)
00132         break;
00133     }
00134       top = temp->prev;
00135       for(temp=loop->prev; temp != loop; temp = temp->prev)
00136     {
00137       if(compInY(temp->tail(), temp->prev->tail()) < 0)
00138         break;
00139     }
00140       bot = temp;
00141     }
00142   //creat increase and decrease chains
00143   vertexArray inc_chain(50); //this is a dynamci array
00144   for(i=1; i<=top->pwlArc->npts-2; i++) 
00145     {
00146       //the first vertex is the top which doesn't below to inc_chain
00147       inc_chain.appendVertex(top->pwlArc->pts[i].param);
00148     }
00149   for(jarc=top->next; jarc != bot; jarc = jarc->next)
00150     {
00151       for(i=0; i<=jarc->pwlArc->npts-2; i++)
00152     {
00153       inc_chain.appendVertex(jarc->pwlArc->pts[i].param);
00154     }
00155       
00156     }
00157   vertexArray dec_chain(50);
00158   for(jarc = top->prev; jarc != bot; jarc = jarc->prev)
00159     {
00160       for(i=jarc->pwlArc->npts-2; i>=0; i--)
00161     {
00162       dec_chain.appendVertex(jarc->pwlArc->pts[i].param);
00163     }
00164     }
00165   for(i=bot->pwlArc->npts-2; i>=1; i--)
00166     {
00167       dec_chain.appendVertex(jarc->pwlArc->pts[i].param);
00168     }     
00169 
00170   monoTriangulationRec(top->tail(), bot->tail(), &inc_chain, 0,
00171                &dec_chain, 0, &backend);
00172 
00173 }
00174 
00175 /********tesselate a rectanlge (OPTIMIZATION**************/
00176 static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend);
00177 
00178 static Int is_rect(Arc_ptr loop)
00179 {
00180   Int nlines =1;
00181   for(Arc_ptr jarc = loop->next; jarc != loop; jarc = jarc->next)
00182     {
00183       nlines++;
00184       if(nlines == 5)
00185     break;
00186     }
00187   if(nlines != 4)
00188     return 0;
00189 
00190 
00191 /*
00192 printf("here1\n");
00193 printf("loop->tail=(%f,%f)\n", loop->tail()[0], loop->tail()[1]);
00194 printf("loop->head=(%f,%f)\n", loop->head()[0], loop->head()[1]);
00195 printf("loop->next->tail=(%f,%f)\n", loop->next->tail()[0], loop->next->tail()[1]);
00196 printf("loop->next->head=(%f,%f)\n", loop->next->head()[0], loop->next->head()[1]);
00197 if(fglu_abs(loop->tail()[0] - loop->head()[0])<0.000001)
00198     printf("equal 1\n");
00199 if(loop->next->tail()[1] == loop->next->head()[1])
00200     printf("equal 2\n");
00201 */
00202 
00203   if( (glu_abs(loop->tail()[0] - loop->head()[0])<=ZERO) && 
00204       (glu_abs(loop->next->tail()[1] - loop->next->head()[1])<=ZERO) &&
00205       (glu_abs(loop->prev->tail()[1] - loop->prev->head()[1])<=ZERO) &&
00206       (glu_abs(loop->prev->prev->tail()[0] - loop->prev->prev->head()[0])<=ZERO)
00207      )
00208     return 1;
00209   else if
00210     ( (glu_abs(loop->tail()[1] - loop->head()[1]) <= ZERO) && 
00211       (glu_abs(loop->next->tail()[0] - loop->next->head()[0]) <= ZERO) &&
00212       (glu_abs(loop->prev->tail()[0] - loop->prev->head()[0]) <= ZERO) &&
00213       (glu_abs(loop->prev->prev->tail()[1] - loop->prev->prev->head()[1]) <= ZERO)
00214      )
00215       return 1;
00216   else
00217     return 0;
00218 }
00219 
00220 inline void  OPT_OUTVERT(TrimVertex& vv, Backend& backend) 
00221 {
00222 
00223 #ifdef USE_OPTTT
00224   glNormal3fv(vv.cache_normal);                         
00225   glVertex3fv(vv.cache_point);
00226 #else
00227 
00228   backend.tmeshvert(&vv);
00229 
00230 #endif
00231 
00232 }
00233 
00234 static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend);
00235 
00236 static void triangulateRect(Arc_ptr loop, Backend& backend, int TB_or_LR, int ulinear, int vlinear)
00237 {
00238   //we know the loop is a rectangle, but not sure which is top
00239   Arc_ptr top, bot, left, right;
00240   if(loop->tail()[1] == loop->head()[1])
00241     {
00242       if(loop->tail()[1] > loop->prev->prev->tail()[1])
00243     {
00244 
00245     top = loop;
00246     }
00247       else{
00248 
00249     top = loop->prev->prev;
00250     }
00251     }
00252   else 
00253     {
00254       if(loop->tail()[0] > loop->prev->prev->tail()[0])
00255     {
00256       //loop is the right arc
00257 
00258       top = loop->next;
00259     }
00260       else
00261     {
00262 
00263       top = loop->prev;
00264     }
00265     }
00266   left = top->next;
00267   bot  = left->next;
00268   right= bot->next;
00269 
00270   //if u, v are both nonlinear, then if the
00271   //boundary is tessellated dense, we also
00272   //sample the inside to get a better tesslletant.
00273   if( (!ulinear) && (!vlinear))
00274     {
00275       int nu = top->pwlArc->npts;
00276       if(nu < bot->pwlArc->npts)
00277     nu = bot->pwlArc->npts;
00278       int nv = left->pwlArc->npts;
00279       if(nv < right->pwlArc->npts)
00280     nv = right->pwlArc->npts;
00281 /*
00282       if(nu > 2 && nv > 2)
00283     {
00284       triangulateRectGen(top, nu-2,  nv-2, backend);
00285       return;
00286     }
00287 */
00288     }
00289 
00290   if(TB_or_LR == 1)
00291     triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend);
00292   else if(TB_or_LR == -1)
00293     triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend);    
00294   else
00295     {
00296       Int maxPointsTB = top->pwlArc->npts + bot->pwlArc->npts;
00297       Int maxPointsLR = left->pwlArc->npts + right->pwlArc->npts;
00298       
00299       if(maxPointsTB < maxPointsLR)
00300     triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend);    
00301       else
00302     triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend);
00303     }
00304 }
00305 
00306 static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend)
00307 { //if(maxPointsTB >= maxPointsLR)
00308     {
00309 
00310       Int d, topd_left, topd_right, botd_left, botd_right, i,j;
00311       d = left->npts /2;
00312 
00313 #ifdef USE_OPTTT
00314       evalLineNOGE(top->pts, top->npts, backend);
00315       evalLineNOGE(bot->pts, bot->npts, backend);
00316       evalLineNOGE(left->pts, left->npts, backend);
00317       evalLineNOGE(right->pts, right->npts, backend);
00318 #endif
00319 
00320       if(top->npts == 2) {
00321     backend.bgntfan();
00322     OPT_OUTVERT(top->pts[0], backend);//the root
00323     for(i=0; i<left->npts; i++){
00324       OPT_OUTVERT(left->pts[i], backend);
00325     }
00326     for(i=1; i<= bot->npts-2; i++){
00327       OPT_OUTVERT(bot->pts[i], backend);
00328     }
00329     backend.endtfan();
00330     
00331     backend.bgntfan();
00332     OPT_OUTVERT(bot->pts[bot->npts-2], backend);
00333     for(i=0; i<right->npts; i++){
00334       OPT_OUTVERT(right->pts[i], backend);
00335     }
00336     backend.endtfan();
00337       }
00338       else if(bot->npts == 2) {
00339     backend.bgntfan();
00340     OPT_OUTVERT(bot->pts[0], backend);//the root
00341     for(i=0; i<right->npts; i++){
00342       OPT_OUTVERT(right->pts[i], backend);
00343     }
00344     for(i=1; i<= top->npts-2; i++){
00345       OPT_OUTVERT(top->pts[i], backend);
00346     }
00347     backend.endtfan();
00348     
00349     backend.bgntfan();
00350     OPT_OUTVERT(top->pts[top->npts-2], backend);
00351     for(i=0; i<left->npts; i++){
00352       OPT_OUTVERT(left->pts[i], backend);
00353     }
00354     backend.endtfan();
00355       }
00356       else { //both top and bot have >=3 points
00357     
00358     backend.bgntfan();
00359     
00360     OPT_OUTVERT(top->pts[top->npts-2], backend);
00361     
00362     for(i=0; i<=d; i++)
00363       {
00364         OPT_OUTVERT(left->pts[i], backend);   
00365       }
00366     backend.endtfan();
00367     
00368     backend.bgntfan();
00369     
00370     OPT_OUTVERT(bot->pts[1], backend);
00371     
00372     OPT_OUTVERT(top->pts[top->npts-2], backend);
00373     
00374     for(i=d; i< left->npts; i++)
00375       {      
00376         OPT_OUTVERT(left->pts[i], backend);      
00377       }
00378     backend.endtfan();
00379 
00380     d = right->npts/2;
00381     //output only when d<right->npts-1 and
00382     //
00383     if(d<right->npts-1)
00384       { 
00385         backend.bgntfan();
00386         //      backend.tmeshvert(& top->pts[1]);
00387         OPT_OUTVERT(top->pts[1], backend);
00388         for(i=d; i< right->npts; i++)
00389           {
00390         //    backend.tmeshvert(& right->pts[i]);
00391         
00392         OPT_OUTVERT(right->pts[i], backend);
00393         
00394           }
00395         backend.endtfan();
00396       }
00397     
00398     backend.bgntfan();
00399     //      backend.tmeshvert(& bot->pts[bot->npts-2]);
00400     OPT_OUTVERT( bot->pts[bot->npts-2], backend);
00401     for(i=0; i<=d; i++)
00402       {
00403         //    backend.tmeshvert(& right->pts[i]);
00404         OPT_OUTVERT(right->pts[i], backend);
00405         
00406       }
00407     
00408     //      backend.tmeshvert(& top->pts[1]);
00409     OPT_OUTVERT(top->pts[1], backend);      
00410     
00411     backend.endtfan();
00412 
00413 
00414     topd_left = top->npts-2;
00415     topd_right = 1; //topd_left>= topd_right
00416 
00417     botd_left = 1;
00418     botd_right = bot->npts-2; //botd_left<= bot_dright
00419 
00420     
00421     if(top->npts < bot->npts)
00422       {
00423         int delta=bot->npts - top->npts;
00424         int u = delta/2;
00425         botd_left = 1+ u;
00426         botd_right = bot->npts-2-( delta-u);        
00427     
00428         if(botd_left >1)
00429           {
00430         backend.bgntfan();
00431         //    backend.tmeshvert(& top->pts[top->npts-2]);
00432         OPT_OUTVERT(top->pts[top->npts-2], backend);
00433         for(i=1; i<= botd_left; i++)
00434           {
00435             //        backend.tmeshvert(& bot->pts[i]);
00436             OPT_OUTVERT(bot->pts[i] , backend);
00437           }
00438         backend.endtfan();
00439           }
00440         if(botd_right < bot->npts-2)
00441           {
00442         backend.bgntfan();
00443         OPT_OUTVERT(top->pts[1], backend);
00444         for(i=botd_right; i<= bot->npts-2; i++)
00445           OPT_OUTVERT(bot->pts[i], backend);
00446         backend.endtfan();
00447           }
00448       }
00449     else if(top->npts> bot->npts)
00450       {
00451         int delta=top->npts-bot->npts;
00452         int u = delta/2;
00453         topd_left = top->npts-2 - u;
00454         topd_right = 1+delta-u;
00455         
00456         if(topd_left < top->npts-2)
00457           {
00458         backend.bgntfan();
00459         //    backend.tmeshvert(& bot->pts[1]);
00460         OPT_OUTVERT(bot->pts[1], backend);
00461         for(i=topd_left; i<= top->npts-2; i++)
00462           {
00463             //        backend.tmeshvert(& top->pts[i]);
00464             OPT_OUTVERT(top->pts[i], backend);
00465           }
00466         backend.endtfan();
00467           }
00468         if(topd_right > 1)
00469           {
00470         backend.bgntfan();
00471         OPT_OUTVERT(bot->pts[bot->npts-2], backend);
00472         for(i=1; i<= topd_right; i++)
00473           OPT_OUTVERT(top->pts[i], backend);
00474         backend.endtfan();
00475           }
00476       }
00477     
00478     if(topd_left <= topd_right) 
00479       return;
00480 
00481     backend.bgnqstrip();
00482     for(j=botd_left, i=topd_left; i>=topd_right; i--,j++)
00483       {
00484         //    backend.tmeshvert(& top->pts[i]);
00485         //    backend.tmeshvert(& bot->pts[j]);
00486         OPT_OUTVERT(top->pts[i], backend);
00487         OPT_OUTVERT(bot->pts[j], backend);
00488       }
00489     backend.endqstrip();
00490     
00491       }
00492     }
00493 }
00494 
00495   
00496 static void triangulateRectCenter(int n_ulines, REAL* u_val, 
00497                   int n_vlines, REAL* v_val,
00498                   Backend& backend)
00499 {
00500 
00501   // XXX this code was patched by Diego Santa Cruz <Diego.SantaCruz@epfl.ch>
00502   // to fix a problem in which glMapGrid2f() was called with bad parameters.
00503   // This has beens submitted to SGI but not integrated as of May 1, 2001.
00504   if(n_ulines>1 && n_vlines>1) {
00505     backend.surfgrid(u_val[0], u_val[n_ulines-1], n_ulines-1, 
00506                      v_val[n_vlines-1], v_val[0], n_vlines-1);
00507     backend.surfmesh(0,0,n_ulines-1,n_vlines-1);
00508   }
00509 
00510   return;
00511 
00512   /*
00513   for(i=0; i<n_vlines-1; i++)
00514     {
00515 
00516       backend.bgnqstrip();
00517       for(j=0; j<n_ulines; j++)
00518     {
00519       trimVert.param[0] = u_val[j];
00520       trimVert.param[1] = v_val[i+1];
00521       backend.tmeshvert(& trimVert);      
00522 
00523       trimVert.param[1] = v_val[i];
00524       backend.tmeshvert(& trimVert);      
00525     }
00526       backend.endqstrip();
00527 
00528     }
00529     */
00530 }
00531 
00532 //it works for top, bot, left ad right, you need ot select correct arguments
00533 static void triangulateRectTopGen(Arc_ptr arc, int n_ulines, REAL* u_val, Real v, int dir, int is_u, Backend& backend)
00534 {
00535 
00536   if(is_u)
00537     {
00538       int i,k;
00539       REAL* upper_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts);
00540       assert(upper_val);
00541       if(dir)
00542     {
00543       for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++)
00544         {
00545           upper_val[k] = arc->pwlArc->pts[i].param[0];
00546         }   
00547       backend.evalUStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[1],
00548                  upper_val,
00549                  n_ulines, v, u_val);
00550     }
00551       else
00552     {
00553       for(k=0,i=0;  i<arc->pwlArc->npts; i++,k++)
00554         {
00555           upper_val[k] = arc->pwlArc->pts[i].param[0];
00556 
00557         }         
00558 
00559       backend.evalUStrip(
00560                  n_ulines, v, u_val,
00561                  arc->pwlArc->npts, arc->pwlArc->pts[0].param[1], upper_val
00562                  );  
00563     }
00564 
00565       free(upper_val);
00566       return;
00567     }
00568   else //is_v
00569     {
00570       int i,k;
00571       REAL* left_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts);
00572       assert(left_val);   
00573       if(dir)
00574     {
00575       for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++)
00576         {
00577           left_val[k] = arc->pwlArc->pts[i].param[1];
00578         }
00579       backend.evalVStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[0],
00580                  left_val,
00581                  n_ulines, v, u_val);
00582     }
00583       else 
00584     {
00585       for(k=0,i=0;  i<arc->pwlArc->npts; i++,k++)
00586         {
00587           left_val[k] = arc->pwlArc->pts[i].param[1];
00588         }
00589        backend.evalVStrip(
00590                  n_ulines, v, u_val,
00591                  arc->pwlArc->npts, arc->pwlArc->pts[0].param[0], left_val
00592                  ); 
00593     }
00594       free(left_val);
00595       return;
00596     }
00597     
00598   //the following is a different version of the above code. If you comment
00599   //the above code, the following code will still work. The reason to leave
00600   //the folliwng code here is purely for testing purpose.
00601   /*
00602   int i,j;
00603   PwlArc* parc = arc->pwlArc;
00604   int d1 = parc->npts-1;
00605   int d2 = 0;
00606   TrimVertex trimVert;
00607   trimVert.nuid = 0;//????
00608   REAL* temp_u_val = u_val;
00609   if(dir ==0) //have to reverse u_val
00610     {
00611       temp_u_val = (REAL*) malloc(sizeof(REAL) * n_ulines);
00612       assert(temp_u_val);
00613       for(i=0; i<n_ulines; i++)
00614     temp_u_val[i] = u_val[n_ulines-1-i];
00615     }
00616   u_val = temp_u_val;
00617 
00618   if(parc->npts > n_ulines)
00619     {
00620       d1 = n_ulines-1;
00621 
00622       backend.bgntfan();
00623       if(is_u){
00624     trimVert.param[0] = u_val[0];
00625     trimVert.param[1] = v;
00626       }
00627       else
00628     {
00629     trimVert.param[1] = u_val[0];
00630     trimVert.param[0] = v;
00631       }
00632       
00633       backend.tmeshvert(& trimVert);
00634       for(i=d1; i< parc->npts; i++)
00635     backend.tmeshvert(& parc->pts[i]);
00636       backend.endtfan();
00637 
00638 
00639     }
00640   else if(parc->npts < n_ulines)
00641     {
00642       d2 = n_ulines-parc->npts;
00643 
00644 
00645       backend.bgntfan();
00646       backend.tmeshvert(& parc->pts[parc->npts-1]);
00647       for(i=0; i<= d2; i++)
00648     {
00649       if(is_u){
00650         trimVert.param[0] = u_val[i];
00651         trimVert.param[1] = v;
00652       }
00653       else
00654         {
00655           trimVert.param[1] = u_val[i];
00656           trimVert.param[0] = v;
00657         }
00658       backend.tmeshvert(&trimVert);
00659     }
00660       backend.endtfan();
00661 
00662     }
00663   if(d1>0){
00664 
00665 
00666     backend.bgnqstrip();
00667     for(i=d1, j=d2; i>=0; i--, j++)
00668       {
00669     backend.tmeshvert(& parc->pts[i]);
00670 
00671     if(is_u){
00672       trimVert.param[0] = u_val[j];
00673       trimVert.param[1] = v;
00674     }
00675     else{
00676       trimVert.param[1] = u_val[j];
00677       trimVert.param[0] = v;
00678     }
00679     backend.tmeshvert(&trimVert);
00680 
00681 
00682     
00683       }
00684     backend.endqstrip();
00685 
00686 
00687   }
00688   if(dir == 0)  //temp_u_val was mallocated
00689     free(temp_u_val);
00690  */
00691 }
00692 
00693 //n_ulines is the number of ulines inside, and n_vlines is the number of vlines
00694 //inside, different from meanings elsewhere!!!
00695 static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend)
00696 {
00697 
00698   int i;
00699   //we know the loop is a rectangle, but not sure which is top
00700   Arc_ptr top, bot, left, right;
00701 
00702   if(equalRect(loop->tail()[1] ,  loop->head()[1]))
00703     {
00704 
00705       if(loop->tail()[1] > loop->prev->prev->tail()[1])
00706     {
00707 
00708     top = loop;
00709     }
00710       else{
00711 
00712     top = loop->prev->prev;
00713     }
00714     }
00715   else 
00716     {
00717       if(loop->tail()[0] > loop->prev->prev->tail()[0])
00718     {
00719       //loop is the right arc
00720 
00721       top = loop->next;
00722     }
00723       else
00724     {
00725 
00726       top = loop->prev;
00727     }
00728     }
00729 
00730   left = top->next;
00731   bot  = left->next;
00732   right= bot->next;
00733 
00734 #ifdef COUNT_TRIANGLES
00735   num_triangles += loop->pwlArc->npts + 
00736                  left->pwlArc->npts + 
00737                  bot->pwlArc->npts + 
00738           right->pwlArc->npts 
00739               + 2*n_ulines + 2*n_vlines 
00740             -8;
00741   num_quads += (n_ulines-1)*(n_vlines-1);
00742 #endif
00743 /*
00744   backend.surfgrid(left->tail()[0], right->tail()[0], n_ulines+1, 
00745            top->tail()[1], bot->tail()[1], n_vlines+1);
00746 //  if(n_ulines>1 && n_vlines>1)
00747     backend.surfmesh(0,0,n_ulines+1,n_vlines+1);
00748 return;
00749 */
00750   REAL* u_val=(REAL*) malloc(sizeof(REAL)*n_ulines);
00751   assert(u_val);
00752   REAL* v_val=(REAL*)malloc(sizeof(REAL) * n_vlines);
00753   assert(v_val);
00754   REAL u_stepsize = (right->tail()[0] - left->tail()[0])/( (REAL) n_ulines+1);
00755   REAL v_stepsize = (top->tail()[1] - bot->tail()[1])/( (REAL) n_vlines+1);
00756   Real temp=left->tail()[0]+u_stepsize;
00757   for(i=0; i<n_ulines; i++)
00758     {
00759       u_val[i] = temp;
00760       temp += u_stepsize;
00761     }
00762   temp = bot->tail()[1] + v_stepsize;
00763   for(i=0; i<n_vlines; i++)
00764     {
00765       v_val[i] = temp;
00766       temp += v_stepsize;
00767     }
00768 
00769   triangulateRectTopGen(top, n_ulines, u_val, v_val[n_vlines-1], 1,1, backend);
00770   triangulateRectTopGen(bot, n_ulines, u_val, v_val[0], 0, 1, backend);
00771   triangulateRectTopGen(left, n_vlines, v_val, u_val[0], 1, 0, backend);
00772   triangulateRectTopGen(right, n_vlines, v_val, u_val[n_ulines-1], 0,0, backend);
00773 
00774 
00775 
00776 
00777   //triangulate the center
00778   triangulateRectCenter(n_ulines, u_val, n_vlines, v_val, backend);
00779 
00780   free(u_val);
00781   free(v_val);
00782   
00783 }
00784   
00785 /***********nextgen tess****************/
00786 #include "sampleMonoPoly.h"
00787 directedLine* arcToDLine(Arc_ptr arc)
00788 {
00789   int i;
00790   Real vert[2];
00791   directedLine* ret;
00792   sampledLine* sline = new sampledLine(arc->pwlArc->npts);
00793   for(i=0; i<arc->pwlArc->npts; i++)
00794     {
00795       vert[0] = arc->pwlArc->pts[i].param[0];
00796       vert[1] = arc->pwlArc->pts[i].param[1];
00797       sline->setPoint(i, vert);
00798     }
00799   ret = new directedLine(INCREASING, sline);
00800   return ret;
00801 }
00802  
00803 /*an pwlArc may not be a straight line*/
00804 directedLine* arcToMultDLines(directedLine* original, Arc_ptr arc)
00805 {
00806   directedLine* ret = original;
00807   int is_linear = 0;
00808   if(arc->pwlArc->npts == 2 )
00809     is_linear = 1;
00810   else if(area(arc->pwlArc->pts[0].param, arc->pwlArc->pts[1].param, arc->pwlArc->pts[arc->pwlArc->npts-1].param) == 0.0)
00811     is_linear = 1;
00812   
00813   if(is_linear)
00814     {
00815       directedLine *dline = arcToDLine(arc);
00816       if(ret == NULL)
00817     ret = dline;
00818       else
00819     ret->insert(dline);
00820       return ret;
00821     }
00822   else /*not linear*/
00823     {
00824       for(Int i=0; i<arc->pwlArc->npts-1; i++)
00825     {
00826       Real vert[2][2];
00827       vert[0][0] = arc->pwlArc->pts[i].param[0];
00828       vert[0][1] = arc->pwlArc->pts[i].param[1];
00829       vert[1][0] = arc->pwlArc->pts[i+1].param[0];
00830       vert[1][1] = arc->pwlArc->pts[i+1].param[1];
00831       
00832       sampledLine *sline = new sampledLine(2, vert);
00833       directedLine *dline = new directedLine(INCREASING, sline);
00834       if(ret == NULL)
00835         ret = dline;
00836       else
00837         ret->insert(dline);
00838     }
00839       return ret;
00840     }
00841 }
00842   
00843      
00844     
00845 directedLine* arcLoopToDLineLoop(Arc_ptr loop)
00846 {
00847   directedLine* ret;
00848 
00849   if(loop == NULL)
00850     return NULL;
00851   ret = arcToMultDLines(NULL, loop);
00852 //ret->printSingle();
00853   for(Arc_ptr temp = loop->next; temp != loop; temp = temp->next){
00854     ret = arcToMultDLines(ret, temp);
00855 //ret->printSingle();
00856   }
00857 
00858   return ret;
00859 }
00860 
00861 /*
00862 void Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid)
00863 {
00864   TrimVertex *trimVert = (TrimVertex*)malloc(sizeof(TrimVertex));
00865   trimVert -> nuid = 0;//????
00866 
00867   Real* u_values = grid->get_u_values();
00868   Real* v_values = grid->get_v_values();
00869 
00870   Int i,j,k,l;
00871 
00872   for(l=0; l<rbArray->get_n_elements(); l++)
00873     {
00874       rectBlock* block = rbArray->get_element(l);
00875       for(k=0, i=block->get_upGridLineIndex(); i>block->get_lowGridLineIndex(); i--, k++)
00876     {
00877 
00878       backend.bgnqstrip();
00879       for(j=block->get_leftIndices()[k+1]; j<= block->get_rightIndices()[k+1]; j++)
00880         {
00881           trimVert->param[0] = u_values[j];
00882           trimVert->param[1] = v_values[i];
00883           backend.tmeshvert(trimVert);
00884 
00885           trimVert->param[1] = v_values[i-1];
00886           backend.tmeshvert(trimVert);
00887 
00888         }
00889       backend.endqstrip();
00890 
00891     }
00892     }
00893   
00894   free(trimVert);
00895 }
00896 */
00897 
00898 void Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid)
00899 {
00900   Int i,j,k;
00901   
00902   Int n_vlines=grid->get_n_vlines();
00903   //the reason to switch the position of v_max and v_min is because of the
00904   //the orientation problem. glEvalMesh generates quad_strip clockwise, but
00905   //we need counter-clockwise.
00906   backend.surfgrid(grid->get_u_min(), grid->get_u_max(), grid->get_n_ulines()-1,
00907            grid->get_v_max(), grid->get_v_min(), n_vlines-1);
00908 
00909 
00910   for(j=0; j<rbArray->get_n_elements(); j++)
00911     {
00912       rectBlock* block = rbArray->get_element(j);
00913       Int low = block->get_lowGridLineIndex();
00914       Int high = block->get_upGridLineIndex();
00915 
00916       for(k=0, i=high; i>low; i--, k++)
00917     {
00918       backend.surfmesh(block->get_leftIndices()[k+1], n_vlines-1-i, block->get_rightIndices()[k+1]-block->get_leftIndices()[k+1], 1);
00919     }
00920     }
00921 }
00922 
00923 
00924 void Slicer::evalStream(primStream* pStream)
00925 {
00926   Int i,j,k;
00927   k=0;
00928 /*  TrimVertex X;*/
00929   TrimVertex *trimVert =/*&X*/  (TrimVertex*)malloc(sizeof(TrimVertex));
00930   trimVert -> nuid = 0;//???
00931   Real* vertices = pStream->get_vertices(); //for efficiency
00932   for(i=0; i<pStream->get_n_prims(); i++)
00933     {
00934 
00935      //ith primitive  has #vertices = lengths[i], type=types[i]
00936       switch(pStream->get_type(i)){
00937       case PRIMITIVE_STREAM_FAN:
00938 
00939     backend.bgntfan();
00940 
00941     for(j=0; j<pStream->get_length(i); j++)
00942       {     
00943         trimVert->param[0] = vertices[k];
00944         trimVert->param[1] = vertices[k+1];
00945         backend.tmeshvert(trimVert);       
00946         
00947 //      backend.tmeshvert(vertices[k], vertices[k+1]);
00948         k += 2;
00949       }
00950     backend.endtfan();
00951     break;
00952     
00953       default:
00954     fprintf(stderr, "evalStream: not implemented yet\n");
00955     exit(1);
00956 
00957       }
00958     }
00959   free(trimVert);
00960 }
00961        
00962        
00963         
00964 
00965 void Slicer::slice_new(Arc_ptr loop)
00966 {
00967 //count++;
00968 //if(count == 78) count=1;
00969 //printf("count=%i\n", count);
00970 //if( ! (4<= count && count <=4)) return;
00971 
00972 
00973   Int num_ulines;
00974   Int num_vlines;
00975   Real uMin, uMax, vMin, vMax;
00976   Real mydu, mydv;
00977   uMin = uMax = loop->tail()[0];
00978   vMin = vMax = loop->tail()[1];
00979   mydu = (du>0)? du: -du;
00980   mydv = (dv>0)? dv: -dv;
00981 
00982   for(Arc_ptr jarc=loop->next; jarc != loop; jarc = jarc->next)
00983    {
00984 
00985      if(jarc->tail()[0] < uMin)
00986        uMin = jarc->tail()[0];
00987      if(jarc->tail()[0] > uMax)
00988        uMax = jarc->tail()[0];
00989      if(jarc->tail()[1] < vMin)
00990        vMin = jarc->tail()[1];
00991      if(jarc->tail()[1] > vMax)
00992        vMax = jarc->tail()[1];
00993    }
00994 
00995   if (uMax == uMin)
00996     return; // prevent divide-by-zero.  Jon Perry.  17 June 2002
00997 
00998   if(mydu > uMax - uMin)
00999     num_ulines = 2;
01000   else
01001     {
01002       num_ulines = 3 + (Int) ((uMax-uMin)/mydu);
01003     }
01004   if(mydv>=vMax-vMin)
01005     num_vlines = 2;
01006   else
01007     {
01008       num_vlines = 2+(Int)((vMax-vMin)/mydv);
01009     }
01010 
01011   Int isRect = is_rect(loop);
01012 
01013   if(isRect && (num_ulines<=2 || num_vlines<=2))
01014     {
01015       if(vlinear)
01016     triangulateRect(loop, backend, 1, ulinear, vlinear);
01017       else if(ulinear)
01018     triangulateRect(loop, backend, -1, ulinear, vlinear);   
01019       else
01020     triangulateRect(loop, backend, 0, ulinear, vlinear);        
01021     }
01022 
01023    else if(isRect)
01024     {
01025       triangulateRectGen(loop, num_ulines-2, num_vlines-2, backend); 
01026     }
01027   else if( (num_ulines<=2 || num_vlines <=2) && ulinear)
01028     {
01029       monoTriangulationFunBackend(loop, compV2InY, &backend);
01030     }
01031   else if( (!ulinear) && (!vlinear) && (num_ulines == 2) && (num_vlines > 2))
01032     {
01033       monoTriangulationFunBackend(loop, compV2InY, &backend);
01034     }
01035   else 
01036     {
01037       directedLine* poly = arcLoopToDLineLoop(loop);
01038 
01039       gridWrap grid(num_ulines, num_vlines, uMin, uMax, vMin, vMax);
01040       primStream pStream(20, 20);
01041       rectBlockArray rbArray(20);
01042 
01043       sampleMonoPoly(poly, &grid, ulinear, vlinear, &pStream, &rbArray);
01044 
01045       evalStream(&pStream);
01046 
01047       evalRBArray(&rbArray, &grid);
01048       
01049 #ifdef COUNT_TRIANGLES
01050       num_triangles += pStream.num_triangles();
01051       num_quads += rbArray.num_quads();
01052 #endif
01053       poly->deleteSinglePolygonWithSline();      
01054     }
01055   
01056 #ifdef COUNT_TRIANGLES
01057   printf("num_triangles=%i\n", num_triangles);
01058   printf("num_quads = %i\n", num_quads);
01059 #endif
01060 }
01061 
01062 void Slicer::slice(Arc_ptr loop)
01063 {
01064 #ifdef USE_READ_FLAG
01065   if(read_flag("flagFile"))
01066     slice_new(loop);
01067   else
01068     slice_old(loop);
01069 
01070 #else
01071     slice_new(loop);
01072 #endif
01073 
01074 }
01075 
01076   
01077 
01078 Slicer::Slicer( Backend &b ) 
01079     : CoveAndTiler( b ), Mesher( b ), backend( b )
01080 {
01081     ulinear = 0;
01082     vlinear = 0;
01083 }
01084 
01085 Slicer::~Slicer()
01086 {
01087 }
01088 
01089 void
01090 Slicer::setisolines( int x )
01091 {
01092     isolines = x;
01093 }
01094 
01095 void
01096 Slicer::setstriptessellation( REAL x, REAL y )
01097 {
01098     assert(x > 0 && y > 0);
01099     du = x;
01100     dv = y;
01101     setDu( du );
01102 }
01103 
01104 void
01105 Slicer::slice_old( Arc_ptr loop )
01106 {
01107     loop->markverts();
01108 
01109     Arc_ptr extrema[4];
01110     loop->getextrema( extrema );
01111 
01112     unsigned int npts = loop->numpts();
01113     TrimRegion::init( npts, extrema[0] );
01114 
01115     Mesher::init( npts );
01116 
01117     long ulines = uarray.init( du, extrema[1], extrema[3] );
01118 //printf("ulines = %i\n", ulines);
01119     Varray varray;
01120     long vlines = varray.init( dv, extrema[0], extrema[2] );
01121 //printf("vlines = %i\n", vlines);
01122     long botv = 0;
01123     long topv;
01124     TrimRegion::init( varray.varray[botv] );
01125     getGridExtent( &extrema[0]->pwlArc->pts[0], &extrema[0]->pwlArc->pts[0] );
01126 
01127     for( long quad=0; quad<varray.numquads; quad++ ) {
01128     backend.surfgrid( uarray.uarray[0], 
01129                uarray.uarray[ulines-1], 
01130                ulines-1, 
01131                varray.vval[quad], 
01132                varray.vval[quad+1], 
01133                varray.voffset[quad+1] - varray.voffset[quad] );
01134 
01135     for( long i=varray.voffset[quad]+1; i <= varray.voffset[quad+1]; i++ ) {
01136             topv = botv++;
01137             advance( topv - varray.voffset[quad], 
01138              botv - varray.voffset[quad], 
01139              varray.varray[botv] );
01140         if( i == vlines )
01141         getPts( extrema[2] );
01142         else
01143         getPts( backend );
01144         getGridExtent();
01145             if( isolines ) {
01146             outline();
01147         } else {
01148         if( canTile() ) 
01149             coveAndTile();
01150         else
01151             mesh();
01152         }
01153         }
01154    }
01155 }
01156 
01157 
01158 void
01159 Slicer::outline( void )
01160 {
01161     GridTrimVertex upper, lower;
01162     Hull::init( );
01163 
01164     backend.bgnoutline();
01165     while( (nextupper( &upper )) ) {
01166     if( upper.isGridVert() )
01167         backend.linevert( upper.g );
01168     else
01169         backend.linevert( upper.t );
01170     }
01171     backend.endoutline();
01172 
01173     backend.bgnoutline();
01174     while( (nextlower( &lower )) ) {
01175     if( lower.isGridVert() )
01176         backend.linevert( lower.g );
01177     else
01178         backend.linevert( lower.t );
01179     }
01180     backend.endoutline();
01181 }
01182 
01183 
01184 void
01185 Slicer::outline( Arc_ptr jarc )
01186 {
01187     jarc->markverts();
01188 
01189     if( jarc->pwlArc->npts >= 2 ) {
01190     backend.bgnoutline();
01191     for( int j = jarc->pwlArc->npts-1; j >= 0; j--  )
01192         backend.linevert( &(jarc->pwlArc->pts[j]) );
01193     backend.endoutline();
01194     }
01195 }
01196 
01197 

Generated on Sun May 27 2012 04:23:41 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.