2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 ** http://oss.sgi.com/projects/FreeB
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
38 * $Date: 2001/03/17 00:25:41 $ $Revision: 1.1 $
39 * $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libnurbs/internals/slicer.cc,v 1.1 2001/03/17 00:25:41 brianp Exp $
45 #include "glimports.h"
52 #include "gridtrimvertex.h"
53 #include "trimvertex.h"
56 #include "polyUtil.h" //for area()
60 /*USE_OPTTT is initiated in trimvertex.h*/
66 //#define USE_READ_FLAG //whether to use new or old tesselator
67 //if defined, it reads "flagFile",
68 // if the number is 1, then use new tess
69 // otherwise, use the old tess.
70 //if not defined, then use new tess.
72 static Int
read_flag(char* name
);
73 Int newtess_flag
= read_flag("flagFile");
76 //#define COUNT_TRIANGLES
77 #ifdef COUNT_TRIANGLES
78 Int num_triangles
= 0;
82 #define max(a,b) ((a>b)? a:b)
83 #define ZERO 0.00001 /*determing whether a loop is a rectngle or not*/
84 #define equalRect(a,b) ((fabs(a-b) <= ZERO)? 1:0) //only used in tessellating a rectangle
86 static Int
is_Convex(Arc_ptr loop
)
88 if(area(loop
->tail(), loop
->head(), loop
->next
->head()) <0 )
90 for(Arc_ptr jarc
= loop
->next
; jarc
!= loop
; jarc
= jarc
->next
)
92 if(area(jarc
->tail(), jarc
->head(), jarc
->next
->head()) < 0)
98 /******triangulate a monotone polygon**************/
99 #include "monoTriangulation.h"
100 static int is_U_monotone(Arc_ptr loop
)
107 cur_sign
= compV2InX(loop
->head(), loop
->tail());
109 n_changes
= (compV2InX(loop
->prev
->head(), loop
->prev
->tail())
112 for(temp
=loop
->next
; temp
!= loop
; temp
= temp
->next
)
114 prev_sign
= cur_sign
;
115 cur_sign
= compV2InX(temp
->head(), temp
->tail());
116 if(cur_sign
!= prev_sign
)
119 printf("***change signe\n");
124 if(n_changes
== 2) return 1;
129 inline int compInY(REAL a
[2], REAL b
[2])
133 else if (a
[1] > b
[1])
140 void monoTriangulationLoop(Arc_ptr loop
, Backend
& backend
, primStream
* pStream
)
143 //find the top, bottom, increasing and decreasing chain
144 //then call monoTrianulation
149 if(compInY(loop
->tail(), loop
->prev
->tail()) < 0)
152 for(temp
= loop
->next
; temp
!= loop
; temp
= temp
->next
)
154 if(compInY(temp
->tail(), temp
->prev
->tail()) > 0)
159 for(temp
=loop
->prev
; temp
!= loop
; temp
= temp
->prev
)
161 if(compInY(temp
->tail(), temp
->prev
->tail()) > 0)
166 else //loop > loop->prev
168 for(temp
=loop
->next
; temp
!= loop
; temp
= temp
->next
)
170 if(compInY(temp
->tail(), temp
->prev
->tail()) < 0)
174 for(temp
=loop
->prev
; temp
!= loop
; temp
= temp
->prev
)
176 if(compInY(temp
->tail(), temp
->prev
->tail()) < 0)
181 //creat increase and decrease chains
182 vertexArray
inc_chain(50); //this is a dynamci array
183 for(i
=1; i
<=top
->pwlArc
->npts
-2; i
++)
185 //the first vertex is the top which doesn't below to inc_chain
186 inc_chain
.appendVertex(top
->pwlArc
->pts
[i
].param
);
188 for(jarc
=top
->next
; jarc
!= bot
; jarc
= jarc
->next
)
190 for(i
=0; i
<=jarc
->pwlArc
->npts
-2; i
++)
192 inc_chain
.appendVertex(jarc
->pwlArc
->pts
[i
].param
);
196 vertexArray
dec_chain(50);
197 for(jarc
= top
->prev
; jarc
!= bot
; jarc
= jarc
->prev
)
199 for(i
=jarc
->pwlArc
->npts
-2; i
>=0; i
--)
201 dec_chain
.appendVertex(jarc
->pwlArc
->pts
[i
].param
);
204 for(i
=bot
->pwlArc
->npts
-2; i
>=1; i
--)
206 dec_chain
.appendVertex(jarc
->pwlArc
->pts
[i
].param
);
209 monoTriangulationRec(top
->tail(), bot
->tail(), &inc_chain
, 0,
210 &dec_chain
, 0, &backend
);
214 /********tesselate a rectanlge (OPTIMIZATION**************/
215 static void triangulateRectGen(Arc_ptr loop
, int n_ulines
, int n_vlines
, Backend
& backend
);
217 static Int
is_rect(Arc_ptr loop
)
220 for(Arc_ptr jarc
= loop
->next
; jarc
!= loop
; jarc
= jarc
->next
)
232 printf("loop->tail=(%f,%f)\n", loop->tail()[0], loop->tail()[1]);
233 printf("loop->head=(%f,%f)\n", loop->head()[0], loop->head()[1]);
234 printf("loop->next->tail=(%f,%f)\n", loop->next->tail()[0], loop->next->tail()[1]);
235 printf("loop->next->head=(%f,%f)\n", loop->next->head()[0], loop->next->head()[1]);
236 if(fabs(loop->tail()[0] - loop->head()[0])<0.000001)
238 if(loop->next->tail()[1] == loop->next->head()[1])
242 if( (fabs(loop
->tail()[0] - loop
->head()[0])<=ZERO
) &&
243 (fabs(loop
->next
->tail()[1] - loop
->next
->head()[1])<=ZERO
) &&
244 (fabs(loop
->prev
->tail()[1] - loop
->prev
->head()[1])<=ZERO
) &&
245 (fabs(loop
->prev
->prev
->tail()[0] - loop
->prev
->prev
->head()[0])<=ZERO
)
249 ( (fabs(loop
->tail()[1] - loop
->head()[1]) <= ZERO
) &&
250 (fabs(loop
->next
->tail()[0] - loop
->next
->head()[0]) <= ZERO
) &&
251 (fabs(loop
->prev
->tail()[0] - loop
->prev
->head()[0]) <= ZERO
) &&
252 (fabs(loop
->prev
->prev
->tail()[1] - loop
->prev
->prev
->head()[1]) <= ZERO
)
260 //a line with the same u for opt
261 static void evalLineNOGE_BU(TrimVertex
*verts
, int n
, Backend
& backend
)
264 backend
.preEvaluateBU(verts
[0].param
[0]);
266 backend
.tmeshvertNOGE_BU(&verts
[i
]);
269 //a line with the same v for opt
270 static void evalLineNOGE_BV(TrimVertex
*verts
, int n
, Backend
& backend
)
273 backend
.preEvaluateBV(verts
[0].param
[1]);
276 backend
.tmeshvertNOGE_BV(&verts
[i
]);
278 static void evalLineNOGE(TrimVertex
*verts
, int n
, Backend
& backend
)
281 if(verts
[0].param
[0] == verts
[n
-1].param
[0]) //all u;s are equal
282 evalLineNOGE_BU(verts
, n
, backend
);
283 else if(verts
[0].param
[1] == verts
[n
-1].param
[1]) //all v's are equal
284 evalLineNOGE_BV(verts
, n
, backend
);
289 backend
.tmeshvertNOGE(&verts
[i
]);
294 inline void OPT_OUTVERT(TrimVertex
& vv
, Backend
& backend
)
298 glNormal3fv(vv
.cache_normal
);
299 glVertex3fv(vv
.cache_point
);
302 backend
.tmeshvert(&vv
);
308 static void triangulateRectAux(PwlArc
* top
, PwlArc
* bot
, PwlArc
* left
, PwlArc
* right
, Backend
& backend
);
310 static void triangulateRect(Arc_ptr loop
, Backend
& backend
, int TB_or_LR
, int ulinear
, int vlinear
)
313 //we know the loop is a rectangle, but not sure which is top
314 Arc_ptr top
, bot
, left
, right
;
315 if(loop
->tail()[1] == loop
->head()[1])
317 if(loop
->tail()[1] > loop
->prev
->prev
->tail()[1])
324 top
= loop
->prev
->prev
;
329 if(loop
->tail()[0] > loop
->prev
->prev
->tail()[0])
331 //loop is the right arc
345 //if u, v are both nonlinear, then if the
346 //boundary is tessellated dense, we also
347 //sample the inside to get a better tesslletant.
348 if( (!ulinear
) && (!vlinear
))
350 int nu
= top
->pwlArc
->npts
;
351 if(nu
< bot
->pwlArc
->npts
)
352 nu
= bot
->pwlArc
->npts
;
353 int nv
= left
->pwlArc
->npts
;
354 if(nv
< right
->pwlArc
->npts
)
355 nv
= right
->pwlArc
->npts
;
359 triangulateRectGen(top, nu-2, nv-2, backend);
366 triangulateRectAux(top
->pwlArc
, bot
->pwlArc
, left
->pwlArc
, right
->pwlArc
, backend
);
367 else if(TB_or_LR
== -1)
368 triangulateRectAux(left
->pwlArc
, right
->pwlArc
, bot
->pwlArc
, top
->pwlArc
, backend
);
371 Int maxPointsTB
= top
->pwlArc
->npts
+ bot
->pwlArc
->npts
;
372 Int maxPointsLR
= left
->pwlArc
->npts
+ right
->pwlArc
->npts
;
374 if(maxPointsTB
< maxPointsLR
)
375 triangulateRectAux(left
->pwlArc
, right
->pwlArc
, bot
->pwlArc
, top
->pwlArc
, backend
);
377 triangulateRectAux(top
->pwlArc
, bot
->pwlArc
, left
->pwlArc
, right
->pwlArc
, backend
);
381 static void triangulateRectAux(PwlArc
* top
, PwlArc
* bot
, PwlArc
* left
, PwlArc
* right
, Backend
& backend
)
382 { //if(maxPointsTB >= maxPointsLR)
385 Int d
, topd_left
, topd_right
, botd_left
, botd_right
, i
,j
;
389 evalLineNOGE(top
->pts
, top
->npts
, backend
);
390 evalLineNOGE(bot
->pts
, bot
->npts
, backend
);
391 evalLineNOGE(left
->pts
, left
->npts
, backend
);
392 evalLineNOGE(right
->pts
, right
->npts
, backend
);
397 OPT_OUTVERT(top
->pts
[0], backend
);//the root
398 for(i
=0; i
<left
->npts
; i
++){
399 OPT_OUTVERT(left
->pts
[i
], backend
);
401 for(i
=1; i
<= bot
->npts
-2; i
++){
402 OPT_OUTVERT(bot
->pts
[i
], backend
);
407 OPT_OUTVERT(bot
->pts
[bot
->npts
-2], backend
);
408 for(i
=0; i
<right
->npts
; i
++){
409 OPT_OUTVERT(right
->pts
[i
], backend
);
413 else if(bot
->npts
== 2) {
415 OPT_OUTVERT(bot
->pts
[0], backend
);//the root
416 for(i
=0; i
<right
->npts
; i
++){
417 OPT_OUTVERT(right
->pts
[i
], backend
);
419 for(i
=1; i
<= top
->npts
-2; i
++){
420 OPT_OUTVERT(top
->pts
[i
], backend
);
425 OPT_OUTVERT(top
->pts
[top
->npts
-2], backend
);
426 for(i
=0; i
<left
->npts
; i
++){
427 OPT_OUTVERT(left
->pts
[i
], backend
);
431 else { //both top and bot have >=3 points
435 OPT_OUTVERT(top
->pts
[top
->npts
-2], backend
);
439 OPT_OUTVERT(left
->pts
[i
], backend
);
445 OPT_OUTVERT(bot
->pts
[1], backend
);
447 OPT_OUTVERT(top
->pts
[top
->npts
-2], backend
);
449 for(i
=d
; i
< left
->npts
; i
++)
451 OPT_OUTVERT(left
->pts
[i
], backend
);
456 //output only when d<right->npts-1 and
461 // backend.tmeshvert(& top->pts[1]);
462 OPT_OUTVERT(top
->pts
[1], backend
);
463 for(i
=d
; i
< right
->npts
; i
++)
465 // backend.tmeshvert(& right->pts[i]);
467 OPT_OUTVERT(right
->pts
[i
], backend
);
474 // backend.tmeshvert(& bot->pts[bot->npts-2]);
475 OPT_OUTVERT( bot
->pts
[bot
->npts
-2], backend
);
478 // backend.tmeshvert(& right->pts[i]);
479 OPT_OUTVERT(right
->pts
[i
], backend
);
483 // backend.tmeshvert(& top->pts[1]);
484 OPT_OUTVERT(top
->pts
[1], backend
);
489 topd_left
= top
->npts
-2;
490 topd_right
= 1; //topd_left>= topd_right
493 botd_right
= bot
->npts
-2; //botd_left<= bot_dright
496 if(top
->npts
< bot
->npts
)
498 int delta
=bot
->npts
- top
->npts
;
501 botd_right
= bot
->npts
-2-( delta
-u
);
506 // backend.tmeshvert(& top->pts[top->npts-2]);
507 OPT_OUTVERT(top
->pts
[top
->npts
-2], backend
);
508 for(i
=1; i
<= botd_left
; i
++)
510 // backend.tmeshvert(& bot->pts[i]);
511 OPT_OUTVERT(bot
->pts
[i
] , backend
);
515 if(botd_right
< bot
->npts
-2)
518 OPT_OUTVERT(top
->pts
[1], backend
);
519 for(i
=botd_right
; i
<= bot
->npts
-2; i
++)
520 OPT_OUTVERT(bot
->pts
[i
], backend
);
524 else if(top
->npts
> bot
->npts
)
526 int delta
=top
->npts
-bot
->npts
;
528 topd_left
= top
->npts
-2 - u
;
529 topd_right
= 1+delta
-u
;
531 if(topd_left
< top
->npts
-2)
534 // backend.tmeshvert(& bot->pts[1]);
535 OPT_OUTVERT(bot
->pts
[1], backend
);
536 for(i
=topd_left
; i
<= top
->npts
-2; i
++)
538 // backend.tmeshvert(& top->pts[i]);
539 OPT_OUTVERT(top
->pts
[i
], backend
);
546 OPT_OUTVERT(bot
->pts
[bot
->npts
-2], backend
);
547 for(i
=1; i
<= topd_right
; i
++)
548 OPT_OUTVERT(top
->pts
[i
], backend
);
553 if(topd_left
<= topd_right
)
557 for(j
=botd_left
, i
=topd_left
; i
>=topd_right
; i
--,j
++)
559 // backend.tmeshvert(& top->pts[i]);
560 // backend.tmeshvert(& bot->pts[j]);
561 OPT_OUTVERT(top
->pts
[i
], backend
);
562 OPT_OUTVERT(bot
->pts
[j
], backend
);
571 static void triangulateRectCenter(int n_ulines
, REAL
* u_val
,
572 int n_vlines
, REAL
* v_val
,
576 trimVert
.nuid
= 0;//????
578 backend
.surfgrid(u_val
[0], u_val
[n_ulines
-1], n_ulines
-1,
579 v_val
[n_vlines
-1], v_val
[0], n_vlines
-1);
581 if(n_ulines
>1 && n_vlines
>1)
582 backend
.surfmesh(0,0,n_ulines
-1,n_vlines
-1);
587 for(i=0; i<n_vlines-1; i++)
591 for(j=0; j<n_ulines; j++)
593 trimVert.param[0] = u_val[j];
594 trimVert.param[1] = v_val[i+1];
595 backend.tmeshvert(& trimVert);
597 trimVert.param[1] = v_val[i];
598 backend.tmeshvert(& trimVert);
606 //it works for top, bot, left ad right, you need ot select correct arguments
607 static void triangulateRectTopGen(Arc_ptr arc
, int n_ulines
, REAL
* u_val
, Real v
, int dir
, int is_u
, Backend
& backend
)
613 REAL
* upper_val
= (REAL
*) malloc(sizeof(REAL
) * arc
->pwlArc
->npts
);
617 for(k
=0,i
=arc
->pwlArc
->npts
-1; i
>=0; i
--,k
++)
619 upper_val
[k
] = arc
->pwlArc
->pts
[i
].param
[0];
621 backend
.evalUStrip(arc
->pwlArc
->npts
, arc
->pwlArc
->pts
[0].param
[1],
627 for(k
=0,i
=0; i
<arc
->pwlArc
->npts
; i
++,k
++)
629 upper_val
[k
] = arc
->pwlArc
->pts
[i
].param
[0];
635 arc
->pwlArc
->npts
, arc
->pwlArc
->pts
[0].param
[1], upper_val
645 REAL
* left_val
= (REAL
*) malloc(sizeof(REAL
) * arc
->pwlArc
->npts
);
649 for(k
=0,i
=arc
->pwlArc
->npts
-1; i
>=0; i
--,k
++)
651 left_val
[k
] = arc
->pwlArc
->pts
[i
].param
[1];
653 backend
.evalVStrip(arc
->pwlArc
->npts
, arc
->pwlArc
->pts
[0].param
[0],
659 for(k
=0,i
=0; i
<arc
->pwlArc
->npts
; i
++,k
++)
661 left_val
[k
] = arc
->pwlArc
->pts
[i
].param
[1];
665 arc
->pwlArc
->npts
, arc
->pwlArc
->pts
[0].param
[0], left_val
672 //the following is a different version of the above code. If you comment
673 //the above code, the following code will still work. The reason to leave
674 //the folliwng code here is purely for testing purpose.
677 PwlArc* parc = arc->pwlArc;
678 int d1 = parc->npts-1;
681 trimVert.nuid = 0;//????
682 REAL* temp_u_val = u_val;
683 if(dir ==0) //have to reverse u_val
685 temp_u_val = (REAL*) malloc(sizeof(REAL) * n_ulines);
687 for(i=0; i<n_ulines; i++)
688 temp_u_val[i] = u_val[n_ulines-1-i];
692 if(parc->npts > n_ulines)
698 trimVert.param[0] = u_val[0];
699 trimVert.param[1] = v;
703 trimVert.param[1] = u_val[0];
704 trimVert.param[0] = v;
707 backend.tmeshvert(& trimVert);
708 for(i=d1; i< parc->npts; i++)
709 backend.tmeshvert(& parc->pts[i]);
714 else if(parc->npts < n_ulines)
716 d2 = n_ulines-parc->npts;
720 backend.tmeshvert(& parc->pts[parc->npts-1]);
721 for(i=0; i<= d2; i++)
724 trimVert.param[0] = u_val[i];
725 trimVert.param[1] = v;
729 trimVert.param[1] = u_val[i];
730 trimVert.param[0] = v;
732 backend.tmeshvert(&trimVert);
741 for(i=d1, j=d2; i>=0; i--, j++)
743 backend.tmeshvert(& parc->pts[i]);
746 trimVert.param[0] = u_val[j];
747 trimVert.param[1] = v;
750 trimVert.param[1] = u_val[j];
751 trimVert.param[0] = v;
753 backend.tmeshvert(&trimVert);
762 if(dir == 0) //temp_u_val was mallocated
767 //n_ulines is the number of ulines inside, and n_vlines is the number of vlines
768 //inside, different from meanings elsewhere!!!
769 static void triangulateRectGen(Arc_ptr loop
, int n_ulines
, int n_vlines
, Backend
& backend
)
773 //we know the loop is a rectangle, but not sure which is top
774 Arc_ptr top
, bot
, left
, right
;
776 if(equalRect(loop
->tail()[1] , loop
->head()[1]))
779 if(loop
->tail()[1] > loop
->prev
->prev
->tail()[1])
786 top
= loop
->prev
->prev
;
791 if(loop
->tail()[0] > loop
->prev
->prev
->tail()[0])
793 //loop is the right arc
808 #ifdef COUNT_TRIANGLES
809 num_triangles
+= loop
->pwlArc
->npts
+
813 + 2*n_ulines
+ 2*n_vlines
815 num_quads
+= (n_ulines
-1)*(n_vlines
-1);
818 backend.surfgrid(left->tail()[0], right->tail()[0], n_ulines+1,
819 top->tail()[1], bot->tail()[1], n_vlines+1);
820 // if(n_ulines>1 && n_vlines>1)
821 backend.surfmesh(0,0,n_ulines+1,n_vlines+1);
824 REAL
* u_val
=(REAL
*) malloc(sizeof(REAL
)*n_ulines
);
826 REAL
* v_val
=(REAL
*)malloc(sizeof(REAL
) * n_vlines
);
828 REAL u_stepsize
= (right
->tail()[0] - left
->tail()[0])/( (REAL
) n_ulines
+1);
829 REAL v_stepsize
= (top
->tail()[1] - bot
->tail()[1])/( (REAL
) n_vlines
+1);
830 Real temp
=left
->tail()[0]+u_stepsize
;
831 for(i
=0; i
<n_ulines
; i
++)
836 temp
= bot
->tail()[1] + v_stepsize
;
837 for(i
=0; i
<n_vlines
; i
++)
843 triangulateRectTopGen(top
, n_ulines
, u_val
, v_val
[n_vlines
-1], 1,1, backend
);
844 triangulateRectTopGen(bot
, n_ulines
, u_val
, v_val
[0], 0, 1, backend
);
845 triangulateRectTopGen(left
, n_vlines
, v_val
, u_val
[0], 1, 0, backend
);
846 triangulateRectTopGen(right
, n_vlines
, v_val
, u_val
[n_ulines
-1], 0,0, backend
);
851 //triangulate the center
852 triangulateRectCenter(n_ulines
, u_val
, n_vlines
, v_val
, backend
);
862 /**********for reading newtess_flag from a file**********/
863 static Int
read_flag(char* name
)
866 FILE* fp
= fopen(name
, "r");
869 fprintf(stderr
, "can't open file %s\n", name
);
872 fscanf(fp
, "%i", &ret
);
878 /***********nextgen tess****************/
879 #include "sampleMonoPoly.h"
880 directedLine
* arcToDLine(Arc_ptr arc
)
885 sampledLine
* sline
= new sampledLine(arc
->pwlArc
->npts
);
886 for(i
=0; i
<arc
->pwlArc
->npts
; i
++)
888 vert
[0] = arc
->pwlArc
->pts
[i
].param
[0];
889 vert
[1] = arc
->pwlArc
->pts
[i
].param
[1];
890 sline
->setPoint(i
, vert
);
892 ret
= new directedLine(INCREASING
, sline
);
896 /*an pwlArc may not be a straight line*/
897 directedLine
* arcToMultDLines(directedLine
* original
, Arc_ptr arc
)
899 directedLine
* ret
= original
;
901 if(arc
->pwlArc
->npts
== 2 )
903 else if(area(arc
->pwlArc
->pts
[0].param
, arc
->pwlArc
->pts
[1].param
, arc
->pwlArc
->pts
[arc
->pwlArc
->npts
-1].param
) == 0.0)
908 directedLine
*dline
= arcToDLine(arc
);
917 for(Int i
=0; i
<arc
->pwlArc
->npts
-1; i
++)
920 vert
[0][0] = arc
->pwlArc
->pts
[i
].param
[0];
921 vert
[0][1] = arc
->pwlArc
->pts
[i
].param
[1];
922 vert
[1][0] = arc
->pwlArc
->pts
[i
+1].param
[0];
923 vert
[1][1] = arc
->pwlArc
->pts
[i
+1].param
[1];
925 sampledLine
*sline
= new sampledLine(2, vert
);
926 directedLine
*dline
= new directedLine(INCREASING
, sline
);
938 directedLine
* arcLoopToDLineLoop(Arc_ptr loop
)
944 ret
= arcToMultDLines(NULL
, loop
);
945 //ret->printSingle();
946 for(Arc_ptr temp
= loop
->next
; temp
!= loop
; temp
= temp
->next
){
947 ret
= arcToMultDLines(ret
, temp
);
948 //ret->printSingle();
955 void Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid)
957 TrimVertex *trimVert = (TrimVertex*)malloc(sizeof(TrimVertex));
958 trimVert -> nuid = 0;//????
960 Real* u_values = grid->get_u_values();
961 Real* v_values = grid->get_v_values();
965 for(l=0; l<rbArray->get_n_elements(); l++)
967 rectBlock* block = rbArray->get_element(l);
968 for(k=0, i=block->get_upGridLineIndex(); i>block->get_lowGridLineIndex(); i--, k++)
972 for(j=block->get_leftIndices()[k+1]; j<= block->get_rightIndices()[k+1]; j++)
974 trimVert->param[0] = u_values[j];
975 trimVert->param[1] = v_values[i];
976 backend.tmeshvert(trimVert);
978 trimVert->param[1] = v_values[i-1];
979 backend.tmeshvert(trimVert);
991 void Slicer::evalRBArray(rectBlockArray
* rbArray
, gridWrap
* grid
)
995 Int n_vlines
=grid
->get_n_vlines();
996 //the reason to switch the position of v_max and v_min is because of the
997 //the orientation problem. glEvalMesh generates quad_strip clockwise, but
998 //we need counter-clockwise.
999 backend
.surfgrid(grid
->get_u_min(), grid
->get_u_max(), grid
->get_n_ulines()-1,
1000 grid
->get_v_max(), grid
->get_v_min(), n_vlines
-1);
1003 for(j
=0; j
<rbArray
->get_n_elements(); j
++)
1005 rectBlock
* block
= rbArray
->get_element(j
);
1006 Int low
= block
->get_lowGridLineIndex();
1007 Int high
= block
->get_upGridLineIndex();
1009 for(k
=0, i
=high
; i
>low
; i
--, k
++)
1011 backend
.surfmesh(block
->get_leftIndices()[k
+1], n_vlines
-1-i
, block
->get_rightIndices()[k
+1]-block
->get_leftIndices()[k
+1], 1);
1017 void Slicer::evalStream(primStream
* pStream
)
1022 TrimVertex
*trimVert
=/*&X*/ (TrimVertex
*)malloc(sizeof(TrimVertex
));
1023 trimVert
-> nuid
= 0;//???
1024 Real
* vertices
= pStream
->get_vertices(); //for efficiency
1025 for(i
=0; i
<pStream
->get_n_prims(); i
++)
1028 //ith primitive has #vertices = lengths[i], type=types[i]
1029 switch(pStream
->get_type(i
)){
1030 case PRIMITIVE_STREAM_FAN
:
1034 for(j
=0; j
<pStream
->get_length(i
); j
++)
1036 trimVert
->param
[0] = vertices
[k
];
1037 trimVert
->param
[1] = vertices
[k
+1];
1038 backend
.tmeshvert(trimVert
);
1040 // backend.tmeshvert(vertices[k], vertices[k+1]);
1047 fprintf(stderr
, "evalStream: not implemented yet\n");
1058 void Slicer::slice_new(Arc_ptr loop
)
1061 //if(count == 78) count=1;
1062 //printf("count=%i\n", count);
1063 //if( ! (4<= count && count <=4)) return;
1068 Real uMin
, uMax
, vMin
, vMax
;
1070 uMin
= uMax
= loop
->tail()[0];
1071 vMin
= vMax
= loop
->tail()[1];
1072 mydu
= (du
>0)? du
: -du
;
1073 mydv
= (dv
>0)? dv
: -dv
;
1075 for(Arc_ptr jarc
=loop
->next
; jarc
!= loop
; jarc
= jarc
->next
)
1078 if(jarc
->tail()[0] < uMin
)
1079 uMin
= jarc
->tail()[0];
1080 if(jarc
->tail()[0] > uMax
)
1081 uMax
= jarc
->tail()[0];
1082 if(jarc
->tail()[1] < vMin
)
1083 vMin
= jarc
->tail()[1];
1084 if(jarc
->tail()[1] > vMax
)
1085 vMax
= jarc
->tail()[1];
1088 if(mydu
> uMax
- uMin
)
1092 num_ulines
= 3 + (Int
) ((uMax
-uMin
)/mydu
);
1098 num_vlines
= 2+(Int
)((vMax
-vMin
)/mydv
);
1101 Int isRect
= is_rect(loop
);
1103 if(isRect
&& (num_ulines
<=2 || num_vlines
<=2))
1106 triangulateRect(loop
, backend
, 1, ulinear
, vlinear
);
1108 triangulateRect(loop
, backend
, -1, ulinear
, vlinear
);
1110 triangulateRect(loop
, backend
, 0, ulinear
, vlinear
);
1115 triangulateRectGen(loop
, num_ulines
-2, num_vlines
-2, backend
);
1117 else if( (num_ulines
<=2 || num_vlines
<=2) && ulinear
)
1119 monoTriangulationFunBackend(loop
, compV2InY
, &backend
);
1121 else if( (!ulinear
) && (!vlinear
) && (num_ulines
== 2) && (num_vlines
> 2))
1123 monoTriangulationFunBackend(loop
, compV2InY
, &backend
);
1127 directedLine
* poly
= arcLoopToDLineLoop(loop
);
1129 gridWrap
grid(num_ulines
, num_vlines
, uMin
, uMax
, vMin
, vMax
);
1130 primStream
pStream(20, 20);
1131 rectBlockArray
rbArray(20);
1133 sampleMonoPoly(poly
, &grid
, ulinear
, vlinear
, &pStream
, &rbArray
);
1135 evalStream(&pStream
);
1137 evalRBArray(&rbArray
, &grid
);
1139 #ifdef COUNT_TRIANGLES
1140 num_triangles
+= pStream
.num_triangles();
1141 num_quads
+= rbArray
.num_quads();
1143 poly
->deleteSinglePolygonWithSline();
1146 #ifdef COUNT_TRIANGLES
1147 printf("num_triangles=%i\n", num_triangles
);
1148 printf("num_quads = %i\n", num_quads
);
1152 void Slicer::slice(Arc_ptr loop
)
1154 #ifdef USE_READ_FLAG
1155 if(read_flag("flagFile"))
1168 Slicer::Slicer( Backend
&b
)
1169 : CoveAndTiler( b
), Mesher( b
), backend( b
)
1180 Slicer::setisolines( int x
)
1186 Slicer::setstriptessellation( REAL x
, REAL y
)
1188 assert(x
> 0 && y
> 0);
1195 Slicer::slice_old( Arc_ptr loop
)
1200 loop
->getextrema( extrema
);
1202 unsigned int npts
= loop
->numpts();
1203 TrimRegion::init( npts
, extrema
[0] );
1205 Mesher::init( npts
);
1207 long ulines
= uarray
.init( du
, extrema
[1], extrema
[3] );
1208 //printf("ulines = %i\n", ulines);
1210 long vlines
= varray
.init( dv
, extrema
[0], extrema
[2] );
1211 //printf("vlines = %i\n", vlines);
1214 TrimRegion::init( varray
.varray
[botv
] );
1215 getGridExtent( &extrema
[0]->pwlArc
->pts
[0], &extrema
[0]->pwlArc
->pts
[0] );
1217 for( long quad
=0; quad
<varray
.numquads
; quad
++ ) {
1218 backend
.surfgrid( uarray
.uarray
[0],
1219 uarray
.uarray
[ulines
-1],
1222 varray
.vval
[quad
+1],
1223 varray
.voffset
[quad
+1] - varray
.voffset
[quad
] );
1225 for( long i
=varray
.voffset
[quad
]+1; i
<= varray
.voffset
[quad
+1]; i
++ ) {
1227 advance( topv
- varray
.voffset
[quad
],
1228 botv
- varray
.voffset
[quad
],
1229 varray
.varray
[botv
] );
1231 getPts( extrema
[2] );
1249 Slicer::outline( void )
1251 GridTrimVertex upper
, lower
;
1254 backend
.bgnoutline();
1255 while( (nextupper( &upper
)) ) {
1256 if( upper
.isGridVert() )
1257 backend
.linevert( upper
.g
);
1259 backend
.linevert( upper
.t
);
1261 backend
.endoutline();
1263 backend
.bgnoutline();
1264 while( (nextlower( &lower
)) ) {
1265 if( lower
.isGridVert() )
1266 backend
.linevert( lower
.g
);
1268 backend
.linevert( lower
.t
);
1270 backend
.endoutline();
1275 Slicer::outline( Arc_ptr jarc
)
1279 if( jarc
->pwlArc
->npts
>= 2 ) {
1280 backend
.bgnoutline();
1281 for( int j
= jarc
->pwlArc
->npts
-1; j
>= 0; j
-- )
1282 backend
.linevert( &(jarc
->pwlArc
->pts
[j
]) );
1283 backend
.endoutline();