source: trunk/src/opengl/glu/nurbs/internals/slicer.cpp

Last change on this file was 3079, checked in by jeroen, 26 years ago

* empty log message *

File size: 32.8 KB
Line 
1/* $Id: slicer.cpp,v 1.2 2000-03-11 09:05:03 jeroen Exp $ */
2/*
3** License Applicability. Except to the extent portions of this file are
4** made subject to an alternative license as permitted in the SGI Free
5** Software License B, Version 1.0 (the "License"), the contents of this
6** file are subject only to the provisions of the License. You may not use
7** this file except in compliance with the License. You may obtain a copy
8** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
9** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10**
11** http://oss.sgi.com/projects/FreeB
12**
13** Note that, as provided in the License, the Software is distributed on an
14** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
15** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
16** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
17** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18**
19** Original Code. The Original Code is: OpenGL Sample Implementation,
20** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
21** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
22** Copyright in any portions created by third parties is as indicated
23** elsewhere herein. All Rights Reserved.
24**
25** Additional Notice Provisions: The application programming interfaces
26** established by SGI in conjunction with the Original Code are The
27** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
28** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
29** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
30** Window System(R) (Version 1.3), released October 19, 1998. This software
31** was created using the OpenGL(R) version 1.2.1 Sample Implementation
32** published by SGI, but has not been independently verified as being
33** compliant with the OpenGL(R) version 1.2.1 Specification.
34*/
35
36/*
37 * slicer.c++
38 *
39 * $Date: 2000-03-11 09:05:03 $ $Revision: 1.2 $
40 * $Header: /home/ktk/tmp/odin/2007/netlabs.cvs/odin32/src/opengl/glu/nurbs/internals/slicer.cpp,v 1.2 2000-03-11 09:05:03 jeroen Exp $
41 */
42
43#include <stdlib.h>
44#include <stdio.h>
45#include <math.h>
46#include "glimports.h"
47#include "mystdio.h"
48#include "myassert.h"
49#include "bufpool.h"
50#include "slicer.h"
51#include "backend.h"
52#include "arc.h"
53#include "gridtrimvertex.h"
54#include "trimvertex.h"
55#include "varray.h"
56
57#include "polyUtil.h" /* for area() */
58
59//static int count=0;
60
61/*USE_OPTTT is initiated in trimvertex.h*/
62
63#ifdef USE_OPTTT
64#include "gl.h"
65#endif
66
67//#define USE_READ_FLAG //whether to use new or old tesselator
68 //if defined, it reads "flagFile",
69 // if the number is 1, then use new tess
70 // otherwise, use the old tess.
71 //if not defined, then use new tess.
72#ifdef USE_READ_FLAG
73static Int read_flag(char* name);
74Int newtess_flag = read_flag("flagFile");
75#endif
76
77//#define COUNT_TRIANGLES
78#ifdef COUNT_TRIANGLES
79Int num_triangles = 0;
80Int num_quads = 0;
81#endif
82
83#ifndef __WIN32OS2__
84#define max(a,b) ((a>b)? a:b)
85#endif
86#define ZERO 0.00001 /*determing whether a loop is a rectngle or not*/
87#define equalRect(a,b) ((fabs(a-b) <= ZERO)? 1:0) //only used in tessellating a rectangle
88
89static Int is_Convex(Arc_ptr loop)
90{
91 if(area(loop->tail(), loop->head(), loop->next->head()) <0 )
92 return 0;
93 for(Arc_ptr jarc = loop->next; jarc != loop; jarc = jarc->next)
94 {
95 if(area(jarc->tail(), jarc->head(), jarc->next->head()) < 0)
96 return 0;
97 }
98 return 1;
99}
100
101/******triangulate a monotone polygon**************/
102#include "monoTriangulation.h"
103static int is_U_monotone(Arc_ptr loop)
104{
105 int n_changes=0;
106 int prev_sign;
107 int cur_sign;
108 Arc_ptr temp;
109
110 cur_sign = compV2InX(loop->head(), loop->tail());
111
112 n_changes = (compV2InX(loop->prev->head(), loop->prev->tail())
113 != cur_sign);
114
115 for(temp=loop->next; temp != loop; temp = temp->next)
116 {
117 prev_sign = cur_sign;
118 cur_sign = compV2InX(temp->head(), temp->tail());
119 if(cur_sign != prev_sign)
120 {
121#ifdef DEBUG
122 printf("***change signe\n");
123#endif
124 n_changes++;
125 }
126 }
127 if(n_changes == 2) return 1;
128 else
129 return 0;
130}
131
132inline int compInY(REAL a[2], REAL b[2])
133{
134 if(a[1] < b[1])
135 return -1;
136 else if (a[1] > b[1])
137 return 1;
138 else if(a[0] > b[0])
139 return 1;
140 else return -1;
141}
142
143void monoTriangulationLoop(Arc_ptr loop, Backend& backend, primStream* pStream)
144{
145 int i;
146 //find the top, bottom, increasing and decreasing chain
147 //then call monoTrianulation
148 Arc_ptr jarc, temp;
149 Arc_ptr top;
150 Arc_ptr bot;
151 top = bot = loop;
152 if(compInY(loop->tail(), loop->prev->tail()) < 0)
153 {
154 //first find bot
155 for(temp = loop->next; temp != loop; temp = temp->next)
156 {
157 if(compInY(temp->tail(), temp->prev->tail()) > 0)
158 break;
159 }
160 bot = temp->prev;
161 //then find top
162 for(temp=loop->prev; temp != loop; temp = temp->prev)
163 {
164 if(compInY(temp->tail(), temp->prev->tail()) > 0)
165 break;
166 }
167 top = temp;
168 }
169 else //loop > loop->prev
170 {
171 for(temp=loop->next; temp != loop; temp = temp->next)
172 {
173 if(compInY(temp->tail(), temp->prev->tail()) < 0)
174 break;
175 }
176 top = temp->prev;
177 for(temp=loop->prev; temp != loop; temp = temp->prev)
178 {
179 if(compInY(temp->tail(), temp->prev->tail()) < 0)
180 break;
181 }
182 bot = temp;
183 }
184 //creat increase and decrease chains
185 vertexArray inc_chain(50); //this is a dynamci array
186 for(i=1; i<=top->pwlArc->npts-2; i++)
187 {
188 //the first vertex is the top which doesn't below to inc_chain
189 inc_chain.appendVertex(top->pwlArc->pts[i].param);
190 }
191 for(jarc=top->next; jarc != bot; jarc = jarc->next)
192 {
193 for(i=0; i<=jarc->pwlArc->npts-2; i++)
194 {
195 inc_chain.appendVertex(jarc->pwlArc->pts[i].param);
196 }
197
198 }
199 vertexArray dec_chain(50);
200 for(jarc = top->prev; jarc != bot; jarc = jarc->prev)
201 {
202 for(i=jarc->pwlArc->npts-2; i>=0; i--)
203 {
204 dec_chain.appendVertex(jarc->pwlArc->pts[i].param);
205 }
206 }
207 for(i=bot->pwlArc->npts-2; i>=1; i--)
208 {
209 dec_chain.appendVertex(jarc->pwlArc->pts[i].param);
210 }
211
212 monoTriangulationRec(top->tail(), bot->tail(), &inc_chain, 0,
213 &dec_chain, 0, &backend);
214
215}
216
217/********tesselate a rectanlge (OPTIMIZATION**************/
218static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend);
219
220static Int is_rect(Arc_ptr loop)
221{
222 Int nlines =1;
223 for(Arc_ptr jarc = loop->next; jarc != loop; jarc = jarc->next)
224 {
225 nlines++;
226 if(nlines == 5)
227 break;
228 }
229 if(nlines != 4)
230 return 0;
231
232
233/*
234printf("here1\n");
235printf("loop->tail=(%f,%f)\n", loop->tail()[0], loop->tail()[1]);
236printf("loop->head=(%f,%f)\n", loop->head()[0], loop->head()[1]);
237printf("loop->next->tail=(%f,%f)\n", loop->next->tail()[0], loop->next->tail()[1]);
238printf("loop->next->head=(%f,%f)\n", loop->next->head()[0], loop->next->head()[1]);
239if(fabs(loop->tail()[0] - loop->head()[0])<0.000001)
240 printf("equal 1\n");
241if(loop->next->tail()[1] == loop->next->head()[1])
242 printf("equal 2\n");
243*/
244
245 if( (fabs(loop->tail()[0] - loop->head()[0])<=ZERO) &&
246 (fabs(loop->next->tail()[1] - loop->next->head()[1])<=ZERO) &&
247 (fabs(loop->prev->tail()[1] - loop->prev->head()[1])<=ZERO) &&
248 (fabs(loop->prev->prev->tail()[0] - loop->prev->prev->head()[0])<=ZERO)
249 )
250 return 1;
251 else if
252 ( (fabs(loop->tail()[1] - loop->head()[1]) <= ZERO) &&
253 (fabs(loop->next->tail()[0] - loop->next->head()[0]) <= ZERO) &&
254 (fabs(loop->prev->tail()[0] - loop->prev->head()[0]) <= ZERO) &&
255 (fabs(loop->prev->prev->tail()[1] - loop->prev->prev->head()[1]) <= ZERO)
256 )
257 return 1;
258 else
259 return 0;
260}
261
262
263//a line with the same u for opt
264static void evalLineNOGE_BU(TrimVertex *verts, int n, Backend& backend)
265{
266 int i;
267 backend.preEvaluateBU(verts[0].param[0]);
268 for(i=0; i<n; i++)
269 backend.tmeshvertNOGE_BU(&verts[i]);
270}
271
272//a line with the same v for opt
273static void evalLineNOGE_BV(TrimVertex *verts, int n, Backend& backend)
274{
275 int i;
276 backend.preEvaluateBV(verts[0].param[1]);
277
278 for(i=0; i<n; i++)
279 backend.tmeshvertNOGE_BV(&verts[i]);
280}
281static void evalLineNOGE(TrimVertex *verts, int n, Backend& backend)
282{
283
284 if(verts[0].param[0] == verts[n-1].param[0]) //all u;s are equal
285 evalLineNOGE_BU(verts, n, backend);
286 else if(verts[0].param[1] == verts[n-1].param[1]) //all v's are equal
287 evalLineNOGE_BV(verts, n, backend);
288 else
289 {
290 int i;
291 for(i=0; i<n; i++)
292 backend.tmeshvertNOGE(&verts[i]);
293 }
294}
295
296
297inline void OPT_OUTVERT(TrimVertex& vv, Backend& backend)
298{
299
300#ifdef USE_OPTTT
301 glNormal3fv(vv.cache_normal);
302 glVertex3fv(vv.cache_point);
303#else
304
305 backend.tmeshvert(&vv);
306
307#endif
308
309}
310
311static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend);
312
313static void triangulateRect(Arc_ptr loop, Backend& backend, int TB_or_LR, int ulinear, int vlinear)
314{
315 int i;
316 //we know the loop is a rectangle, but not sure which is top
317 Arc_ptr top, bot, left, right;
318 if(loop->tail()[1] == loop->head()[1])
319 {
320 if(loop->tail()[1] > loop->prev->prev->tail()[1])
321 {
322
323 top = loop;
324 }
325 else{
326
327 top = loop->prev->prev;
328 }
329 }
330 else
331 {
332 if(loop->tail()[0] > loop->prev->prev->tail()[0])
333 {
334 //loop is the right arc
335
336 top = loop->next;
337 }
338 else
339 {
340
341 top = loop->prev;
342 }
343 }
344 left = top->next;
345 bot = left->next;
346 right= bot->next;
347
348 //if u, v are both nonlinear, then if the
349 //boundary is tessellated dense, we also
350 //sample the inside to get a better tesslletant.
351 if( (!ulinear) && (!vlinear))
352 {
353 int nu = top->pwlArc->npts;
354 if(nu < bot->pwlArc->npts)
355 nu = bot->pwlArc->npts;
356 int nv = left->pwlArc->npts;
357 if(nv < right->pwlArc->npts)
358 nv = right->pwlArc->npts;
359/*
360 if(nu > 2 && nv > 2)
361 {
362 triangulateRectGen(top, nu-2, nv-2, backend);
363 return;
364 }
365*/
366 }
367
368 if(TB_or_LR == 1)
369 triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend);
370 else if(TB_or_LR == -1)
371 triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend);
372 else
373 {
374 Int maxPointsTB = top->pwlArc->npts + bot->pwlArc->npts;
375 Int maxPointsLR = left->pwlArc->npts + right->pwlArc->npts;
376
377 if(maxPointsTB < maxPointsLR)
378 triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend);
379 else
380 triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend);
381 }
382}
383
384static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend)
385{ //if(maxPointsTB >= maxPointsLR)
386 {
387
388 Int d, topd_left, topd_right, botd_left, botd_right, i,j;
389 d = left->npts /2;
390
391#ifdef USE_OPTTT
392 evalLineNOGE(top->pts, top->npts, backend);
393 evalLineNOGE(bot->pts, bot->npts, backend);
394 evalLineNOGE(left->pts, left->npts, backend);
395 evalLineNOGE(right->pts, right->npts, backend);
396#endif
397
398 if(top->npts == 2) {
399 backend.bgntfan();
400 OPT_OUTVERT(top->pts[0], backend);//the root
401 for(i=0; i<left->npts; i++){
402 OPT_OUTVERT(left->pts[i], backend);
403 }
404 for(i=1; i<= bot->npts-2; i++){
405 OPT_OUTVERT(bot->pts[i], backend);
406 }
407 backend.endtfan();
408
409 backend.bgntfan();
410 OPT_OUTVERT(bot->pts[bot->npts-2], backend);
411 for(i=0; i<right->npts; i++){
412 OPT_OUTVERT(right->pts[i], backend);
413 }
414 backend.endtfan();
415 }
416 else if(bot->npts == 2) {
417 backend.bgntfan();
418 OPT_OUTVERT(bot->pts[0], backend);//the root
419 for(i=0; i<right->npts; i++){
420 OPT_OUTVERT(right->pts[i], backend);
421 }
422 for(i=1; i<= top->npts-2; i++){
423 OPT_OUTVERT(top->pts[i], backend);
424 }
425 backend.endtfan();
426
427 backend.bgntfan();
428 OPT_OUTVERT(top->pts[top->npts-2], backend);
429 for(i=0; i<left->npts; i++){
430 OPT_OUTVERT(left->pts[i], backend);
431 }
432 backend.endtfan();
433 }
434 else { //both top and bot have >=3 points
435
436 backend.bgntfan();
437
438 OPT_OUTVERT(top->pts[top->npts-2], backend);
439
440 for(i=0; i<=d; i++)
441 {
442 OPT_OUTVERT(left->pts[i], backend);
443 }
444 backend.endtfan();
445
446 backend.bgntfan();
447
448 OPT_OUTVERT(bot->pts[1], backend);
449
450 OPT_OUTVERT(top->pts[top->npts-2], backend);
451
452 for(i=d; i< left->npts; i++)
453 {
454 OPT_OUTVERT(left->pts[i], backend);
455 }
456 backend.endtfan();
457
458 d = right->npts/2;
459 //output only when d<right->npts-1 and
460 //
461 if(d<right->npts-1)
462 {
463 backend.bgntfan();
464 // backend.tmeshvert(& top->pts[1]);
465 OPT_OUTVERT(top->pts[1], backend);
466 for(i=d; i< right->npts; i++)
467 {
468 // backend.tmeshvert(& right->pts[i]);
469
470 OPT_OUTVERT(right->pts[i], backend);
471
472 }
473 backend.endtfan();
474 }
475
476 backend.bgntfan();
477 // backend.tmeshvert(& bot->pts[bot->npts-2]);
478 OPT_OUTVERT( bot->pts[bot->npts-2], backend);
479 for(i=0; i<=d; i++)
480 {
481 // backend.tmeshvert(& right->pts[i]);
482 OPT_OUTVERT(right->pts[i], backend);
483
484 }
485
486 // backend.tmeshvert(& top->pts[1]);
487 OPT_OUTVERT(top->pts[1], backend);
488
489 backend.endtfan();
490
491
492 topd_left = top->npts-2;
493 topd_right = 1; //topd_left>= topd_right
494
495 botd_left = 1;
496 botd_right = bot->npts-2; //botd_left<= bot_dright
497
498
499 if(top->npts < bot->npts)
500 {
501 int delta=bot->npts - top->npts;
502 int u = delta/2;
503 botd_left = 1+ u;
504 botd_right = bot->npts-2-( delta-u);
505
506 if(botd_left >1)
507 {
508 backend.bgntfan();
509 // backend.tmeshvert(& top->pts[top->npts-2]);
510 OPT_OUTVERT(top->pts[top->npts-2], backend);
511 for(i=1; i<= botd_left; i++)
512 {
513 // backend.tmeshvert(& bot->pts[i]);
514 OPT_OUTVERT(bot->pts[i] , backend);
515 }
516 backend.endtfan();
517 }
518 if(botd_right < bot->npts-2)
519 {
520 backend.bgntfan();
521 OPT_OUTVERT(top->pts[1], backend);
522 for(i=botd_right; i<= bot->npts-2; i++)
523 OPT_OUTVERT(bot->pts[i], backend);
524 backend.endtfan();
525 }
526 }
527 else if(top->npts> bot->npts)
528 {
529 int delta=top->npts-bot->npts;
530 int u = delta/2;
531 topd_left = top->npts-2 - u;
532 topd_right = 1+delta-u;
533
534 if(topd_left < top->npts-2)
535 {
536 backend.bgntfan();
537 // backend.tmeshvert(& bot->pts[1]);
538 OPT_OUTVERT(bot->pts[1], backend);
539 for(i=topd_left; i<= top->npts-2; i++)
540 {
541 // backend.tmeshvert(& top->pts[i]);
542 OPT_OUTVERT(top->pts[i], backend);
543 }
544 backend.endtfan();
545 }
546 if(topd_right > 1)
547 {
548 backend.bgntfan();
549 OPT_OUTVERT(bot->pts[bot->npts-2], backend);
550 for(i=1; i<= topd_right; i++)
551 OPT_OUTVERT(top->pts[i], backend);
552 backend.endtfan();
553 }
554 }
555
556 if(topd_left <= topd_right)
557 return;
558
559 backend.bgnqstrip();
560 for(j=botd_left, i=topd_left; i>=topd_right; i--,j++)
561 {
562 // backend.tmeshvert(& top->pts[i]);
563 // backend.tmeshvert(& bot->pts[j]);
564 OPT_OUTVERT(top->pts[i], backend);
565 OPT_OUTVERT(bot->pts[j], backend);
566 }
567 backend.endqstrip();
568
569 }
570 }
571}
572
573
574static void triangulateRectCenter(int n_ulines, REAL* u_val,
575 int n_vlines, REAL* v_val,
576 Backend& backend)
577{
578 TrimVertex trimVert;
579 trimVert.nuid = 0;//????
580
581 backend.surfgrid(u_val[0], u_val[n_ulines-1], n_ulines-1,
582 v_val[n_vlines-1], v_val[0], n_vlines-1);
583
584 if(n_ulines>1 && n_vlines>1)
585 backend.surfmesh(0,0,n_ulines-1,n_vlines-1);
586
587 return;
588
589 /*
590 for(i=0; i<n_vlines-1; i++)
591 {
592
593 backend.bgnqstrip();
594 for(j=0; j<n_ulines; j++)
595 {
596 trimVert.param[0] = u_val[j];
597 trimVert.param[1] = v_val[i+1];
598 backend.tmeshvert(& trimVert);
599
600 trimVert.param[1] = v_val[i];
601 backend.tmeshvert(& trimVert);
602 }
603 backend.endqstrip();
604
605 }
606 */
607}
608
609//it works for top, bot, left ad right, you need ot select correct arguments
610static void triangulateRectTopGen(Arc_ptr arc, int n_ulines, REAL* u_val, Real v, int dir, int is_u, Backend& backend)
611{
612
613 if(is_u)
614 {
615 int i,k;
616 REAL* upper_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts);
617 assert(upper_val);
618 if(dir)
619 {
620 for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++)
621 {
622 upper_val[k] = arc->pwlArc->pts[i].param[0];
623 }
624 backend.evalUStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[1],
625 upper_val,
626 n_ulines, v, u_val);
627 }
628 else
629 {
630 for(k=0,i=0; i<arc->pwlArc->npts; i++,k++)
631 {
632 upper_val[k] = arc->pwlArc->pts[i].param[0];
633
634 }
635
636 backend.evalUStrip(
637 n_ulines, v, u_val,
638 arc->pwlArc->npts, arc->pwlArc->pts[0].param[1], upper_val
639 );
640 }
641
642 free(upper_val);
643 return;
644 }
645 else //is_v
646 {
647 int i,k;
648 REAL* left_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts);
649 assert(left_val);
650 if(dir)
651 {
652 for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++)
653 {
654 left_val[k] = arc->pwlArc->pts[i].param[1];
655 }
656 backend.evalVStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[0],
657 left_val,
658 n_ulines, v, u_val);
659 }
660 else
661 {
662 for(k=0,i=0; i<arc->pwlArc->npts; i++,k++)
663 {
664 left_val[k] = arc->pwlArc->pts[i].param[1];
665 }
666 backend.evalVStrip(
667 n_ulines, v, u_val,
668 arc->pwlArc->npts, arc->pwlArc->pts[0].param[0], left_val
669 );
670 }
671 free(left_val);
672 return;
673 }
674
675 //the following is a different version of the above code. If you comment
676 //the above code, the following code will still work. The reason to leave
677 //the folliwng code here is purely for testing purpose.
678 /*
679 int i,j;
680 PwlArc* parc = arc->pwlArc;
681 int d1 = parc->npts-1;
682 int d2 = 0;
683 TrimVertex trimVert;
684 trimVert.nuid = 0;//????
685 REAL* temp_u_val = u_val;
686 if(dir ==0) //have to reverse u_val
687 {
688 temp_u_val = (REAL*) malloc(sizeof(REAL) * n_ulines);
689 assert(temp_u_val);
690 for(i=0; i<n_ulines; i++)
691 temp_u_val[i] = u_val[n_ulines-1-i];
692 }
693 u_val = temp_u_val;
694
695 if(parc->npts > n_ulines)
696 {
697 d1 = n_ulines-1;
698
699 backend.bgntfan();
700 if(is_u){
701 trimVert.param[0] = u_val[0];
702 trimVert.param[1] = v;
703 }
704 else
705 {
706 trimVert.param[1] = u_val[0];
707 trimVert.param[0] = v;
708 }
709
710 backend.tmeshvert(& trimVert);
711 for(i=d1; i< parc->npts; i++)
712 backend.tmeshvert(& parc->pts[i]);
713 backend.endtfan();
714
715
716 }
717 else if(parc->npts < n_ulines)
718 {
719 d2 = n_ulines-parc->npts;
720
721
722 backend.bgntfan();
723 backend.tmeshvert(& parc->pts[parc->npts-1]);
724 for(i=0; i<= d2; i++)
725 {
726 if(is_u){
727 trimVert.param[0] = u_val[i];
728 trimVert.param[1] = v;
729 }
730 else
731 {
732 trimVert.param[1] = u_val[i];
733 trimVert.param[0] = v;
734 }
735 backend.tmeshvert(&trimVert);
736 }
737 backend.endtfan();
738
739 }
740 if(d1>0){
741
742
743 backend.bgnqstrip();
744 for(i=d1, j=d2; i>=0; i--, j++)
745 {
746 backend.tmeshvert(& parc->pts[i]);
747
748 if(is_u){
749 trimVert.param[0] = u_val[j];
750 trimVert.param[1] = v;
751 }
752 else{
753 trimVert.param[1] = u_val[j];
754 trimVert.param[0] = v;
755 }
756 backend.tmeshvert(&trimVert);
757
758
759
760 }
761 backend.endqstrip();
762
763
764 }
765 if(dir == 0) //temp_u_val was mallocated
766 free(temp_u_val);
767 */
768}
769
770//n_ulines is the number of ulines inside, and n_vlines is the number of vlines
771//inside, different from meanings elsewhere!!!
772static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend)
773{
774
775 int i;
776 //we know the loop is a rectangle, but not sure which is top
777 Arc_ptr top, bot, left, right;
778
779 if(equalRect(loop->tail()[1] , loop->head()[1]))
780 {
781
782 if(loop->tail()[1] > loop->prev->prev->tail()[1])
783 {
784
785 top = loop;
786 }
787 else{
788
789 top = loop->prev->prev;
790 }
791 }
792 else
793 {
794 if(loop->tail()[0] > loop->prev->prev->tail()[0])
795 {
796 //loop is the right arc
797
798 top = loop->next;
799 }
800 else
801 {
802
803 top = loop->prev;
804 }
805 }
806
807 left = top->next;
808 bot = left->next;
809 right= bot->next;
810
811#ifdef COUNT_TRIANGLES
812 num_triangles += loop->pwlArc->npts +
813 left->pwlArc->npts +
814 bot->pwlArc->npts +
815 right->pwlArc->npts
816 + 2*n_ulines + 2*n_vlines
817 -8;
818 num_quads += (n_ulines-1)*(n_vlines-1);
819#endif
820/*
821 backend.surfgrid(left->tail()[0], right->tail()[0], n_ulines+1,
822 top->tail()[1], bot->tail()[1], n_vlines+1);
823// if(n_ulines>1 && n_vlines>1)
824 backend.surfmesh(0,0,n_ulines+1,n_vlines+1);
825return;
826*/
827 REAL* u_val=(REAL*) malloc(sizeof(REAL)*n_ulines);
828 assert(u_val);
829 REAL* v_val=(REAL*)malloc(sizeof(REAL) * n_vlines);
830 assert(v_val);
831 REAL u_stepsize = (right->tail()[0] - left->tail()[0])/( (REAL) n_ulines+1);
832 REAL v_stepsize = (top->tail()[1] - bot->tail()[1])/( (REAL) n_vlines+1);
833 Real temp=left->tail()[0]+u_stepsize;
834 for(i=0; i<n_ulines; i++)
835 {
836 u_val[i] = temp;
837 temp += u_stepsize;
838 }
839 temp = bot->tail()[1] + v_stepsize;
840 for(i=0; i<n_vlines; i++)
841 {
842 v_val[i] = temp;
843 temp += v_stepsize;
844 }
845
846 triangulateRectTopGen(top, n_ulines, u_val, v_val[n_vlines-1], 1,1, backend);
847 triangulateRectTopGen(bot, n_ulines, u_val, v_val[0], 0, 1, backend);
848 triangulateRectTopGen(left, n_vlines, v_val, u_val[0], 1, 0, backend);
849 triangulateRectTopGen(right, n_vlines, v_val, u_val[n_ulines-1], 0,0, backend);
850
851
852
853
854 //triangulate the center
855 triangulateRectCenter(n_ulines, u_val, n_vlines, v_val, backend);
856
857 free(u_val);
858 free(v_val);
859
860}
861
862
863
864
865/**********for reading newtess_flag from a file**********/
866static Int read_flag(char* name)
867{
868 Int ret;
869 FILE* fp = fopen(name, "r");
870 if(fp == NULL)
871 {
872 fprintf(stderr, "can't open file %s\n", name);
873 exit(1);
874 }
875 fscanf(fp, "%i", &ret);
876 fclose(fp);
877 return ret;
878}
879
880
881/***********nextgen tess****************/
882#include "sampleMonoPoly.h"
883directedLine* arcToDLine(Arc_ptr arc)
884{
885 int i;
886 Real vert[2];
887 directedLine* ret;
888 sampledLine* sline = new sampledLine(arc->pwlArc->npts);
889 for(i=0; i<arc->pwlArc->npts; i++)
890 {
891 vert[0] = arc->pwlArc->pts[i].param[0];
892 vert[1] = arc->pwlArc->pts[i].param[1];
893 sline->setPoint(i, vert);
894 }
895 ret = new directedLine(INCREASING, sline);
896 return ret;
897}
898
899/*an pwlArc may not be a straight line*/
900directedLine* arcToMultDLines(directedLine* original, Arc_ptr arc)
901{
902 directedLine* ret = original;
903 int is_linear = 0;
904 if(arc->pwlArc->npts == 2 )
905 is_linear = 1;
906 else if(area(arc->pwlArc->pts[0].param, arc->pwlArc->pts[1].param, arc->pwlArc->pts[arc->pwlArc->npts-1].param) == 0.0)
907 is_linear = 1;
908
909 if(is_linear)
910 {
911 directedLine *dline = arcToDLine(arc);
912 if(ret == NULL)
913 ret = dline;
914 else
915 ret->insert(dline);
916 return ret;
917 }
918 else /*not linear*/
919 {
920 for(Int i=0; i<arc->pwlArc->npts-1; i++)
921 {
922 Real vert[2][2];
923 vert[0][0] = arc->pwlArc->pts[i].param[0];
924 vert[0][1] = arc->pwlArc->pts[i].param[1];
925 vert[1][0] = arc->pwlArc->pts[i+1].param[0];
926 vert[1][1] = arc->pwlArc->pts[i+1].param[1];
927
928 sampledLine *sline = new sampledLine(2, vert);
929 directedLine *dline = new directedLine(INCREASING, sline);
930 if(ret == NULL)
931 ret = dline;
932 else
933 ret->insert(dline);
934 }
935 return ret;
936 }
937}
938
939
940
941directedLine* arcLoopToDLineLoop(Arc_ptr loop)
942{
943 directedLine* ret;
944
945 if(loop == NULL)
946 return NULL;
947 ret = arcToMultDLines(NULL, loop);
948//ret->printSingle();
949 for(Arc_ptr temp = loop->next; temp != loop; temp = temp->next){
950 ret = arcToMultDLines(ret, temp);
951//ret->printSingle();
952 }
953
954 return ret;
955}
956
957/*
958void Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid)
959{
960 TrimVertex *trimVert = (TrimVertex*)malloc(sizeof(TrimVertex));
961 trimVert -> nuid = 0;//????
962
963 Real* u_values = grid->get_u_values();
964 Real* v_values = grid->get_v_values();
965
966 Int i,j,k,l;
967
968 for(l=0; l<rbArray->get_n_elements(); l++)
969 {
970 rectBlock* block = rbArray->get_element(l);
971 for(k=0, i=block->get_upGridLineIndex(); i>block->get_lowGridLineIndex(); i--, k++)
972 {
973
974 backend.bgnqstrip();
975 for(j=block->get_leftIndices()[k+1]; j<= block->get_rightIndices()[k+1]; j++)
976 {
977 trimVert->param[0] = u_values[j];
978 trimVert->param[1] = v_values[i];
979 backend.tmeshvert(trimVert);
980
981 trimVert->param[1] = v_values[i-1];
982 backend.tmeshvert(trimVert);
983
984 }
985 backend.endqstrip();
986
987 }
988 }
989
990 free(trimVert);
991}
992*/
993
994void Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid)
995{
996 Int i,j,k;
997
998 Int n_vlines=grid->get_n_vlines();
999 //the reason to switch the position of v_max and v_min is because of the
1000 //the orientation problem. glEvalMesh generates quad_strip clockwise, but
1001 //we need counter-clockwise.
1002 backend.surfgrid(grid->get_u_min(), grid->get_u_max(), grid->get_n_ulines()-1,
1003 grid->get_v_max(), grid->get_v_min(), n_vlines-1);
1004
1005
1006 for(j=0; j<rbArray->get_n_elements(); j++)
1007 {
1008 rectBlock* block = rbArray->get_element(j);
1009 Int low = block->get_lowGridLineIndex();
1010 Int high = block->get_upGridLineIndex();
1011
1012 for(k=0, i=high; i>low; i--, k++)
1013 {
1014 backend.surfmesh(block->get_leftIndices()[k+1], n_vlines-1-i, block->get_rightIndices()[k+1]-block->get_leftIndices()[k+1], 1);
1015 }
1016 }
1017}
1018
1019
1020void Slicer::evalStream(primStream* pStream)
1021{
1022 Int i,j,k;
1023 k=0;
1024/* TrimVertex X;*/
1025 TrimVertex *trimVert =/*&X*/ (TrimVertex*)malloc(sizeof(TrimVertex));
1026 trimVert -> nuid = 0;//???
1027 Real* vertices = pStream->get_vertices(); //for efficiency
1028 for(i=0; i<pStream->get_n_prims(); i++)
1029 {
1030
1031 //ith primitive has #vertices = lengths[i], type=types[i]
1032 switch(pStream->get_type(i)){
1033 case PRIMITIVE_STREAM_FAN:
1034
1035 backend.bgntfan();
1036
1037 for(j=0; j<pStream->get_length(i); j++)
1038 {
1039 trimVert->param[0] = vertices[k];
1040 trimVert->param[1] = vertices[k+1];
1041 backend.tmeshvert(trimVert);
1042
1043// backend.tmeshvert(vertices[k], vertices[k+1]);
1044 k += 2;
1045 }
1046 backend.endtfan();
1047 break;
1048
1049 default:
1050 fprintf(stderr, "evalStream: not implemented yet\n");
1051 exit(1);
1052
1053 }
1054 }
1055 free(trimVert);
1056}
1057
1058
1059
1060
1061void Slicer::slice_new(Arc_ptr loop)
1062{
1063//count++;
1064//if(count == 78) count=1;
1065//printf("count=%i\n", count);
1066//if( ! (4<= count && count <=4)) return;
1067
1068
1069 Int num_ulines;
1070 Int num_vlines;
1071 Real uMin, uMax, vMin, vMax;
1072 Real mydu, mydv;
1073 uMin = uMax = loop->tail()[0];
1074 vMin = vMax = loop->tail()[1];
1075 mydu = (du>0)? du: -du;
1076 mydv = (dv>0)? dv: -dv;
1077
1078 for(Arc_ptr jarc=loop->next; jarc != loop; jarc = jarc->next)
1079 {
1080
1081 if(jarc->tail()[0] < uMin)
1082 uMin = jarc->tail()[0];
1083 if(jarc->tail()[0] > uMax)
1084 uMax = jarc->tail()[0];
1085 if(jarc->tail()[1] < vMin)
1086 vMin = jarc->tail()[1];
1087 if(jarc->tail()[1] > vMax)
1088 vMax = jarc->tail()[1];
1089 }
1090
1091 if(mydu > uMax - uMin)
1092 num_ulines = 2;
1093 else
1094 {
1095 num_ulines = 3 + (Int) ((uMax-uMin)/mydu);
1096 }
1097 if(mydv>=vMax-vMin)
1098 num_vlines = 2;
1099 else
1100 {
1101 num_vlines = 2+(Int)((vMax-vMin)/mydv);
1102 }
1103
1104 Int isRect = is_rect(loop);
1105
1106 if(isRect && (num_ulines<=2 || num_vlines<=2))
1107 {
1108 if(vlinear)
1109 triangulateRect(loop, backend, 1, ulinear, vlinear);
1110 else if(ulinear)
1111 triangulateRect(loop, backend, -1, ulinear, vlinear);
1112 else
1113 triangulateRect(loop, backend, 0, ulinear, vlinear);
1114 }
1115
1116 else if(isRect)
1117 {
1118 triangulateRectGen(loop, num_ulines-2, num_vlines-2, backend);
1119 }
1120 else if( (num_ulines<=2 || num_vlines <=2) && ulinear)
1121 {
1122 monoTriangulationFunBackend(loop, compV2InY, &backend);
1123 }
1124 else if( (!ulinear) && (!vlinear) && (num_ulines == 2) && (num_vlines > 2))
1125 {
1126 monoTriangulationFunBackend(loop, compV2InY, &backend);
1127 }
1128 else
1129 {
1130 directedLine* poly = arcLoopToDLineLoop(loop);
1131
1132 gridWrap grid(num_ulines, num_vlines, uMin, uMax, vMin, vMax);
1133 primStream pStream(20, 20);
1134 rectBlockArray rbArray(20);
1135
1136 sampleMonoPoly(poly, &grid, ulinear, vlinear, &pStream, &rbArray);
1137
1138 evalStream(&pStream);
1139
1140 evalRBArray(&rbArray, &grid);
1141
1142#ifdef COUNT_TRIANGLES
1143 num_triangles += pStream.num_triangles();
1144 num_quads += rbArray.num_quads();
1145#endif
1146 poly->deleteSinglePolygonWithSline();
1147 }
1148
1149#ifdef COUNT_TRIANGLES
1150 printf("num_triangles=%i\n", num_triangles);
1151 printf("num_quads = %i\n", num_quads);
1152#endif
1153
1154}
1155
1156void Slicer::slice(Arc_ptr loop)
1157{
1158#ifdef USE_READ_FLAG
1159 if(read_flag("flagFile"))
1160 slice_new(loop);
1161 else
1162 slice_old(loop);
1163
1164#else
1165 slice_new(loop);
1166#endif
1167
1168}
1169
1170
1171
1172Slicer::Slicer( Backend &b )
1173 : CoveAndTiler( b ), Mesher( b ), backend( b )
1174{
1175 ulinear = 0;
1176 vlinear = 0;
1177}
1178
1179Slicer::~Slicer()
1180{
1181}
1182
1183void
1184Slicer::setisolines( int x )
1185{
1186 isolines = x;
1187}
1188
1189void
1190Slicer::setstriptessellation( REAL x, REAL y )
1191{
1192 assert(x > 0 && y > 0);
1193 du = x;
1194 dv = y;
1195 setDu( du );
1196}
1197
1198void
1199Slicer::slice_old( Arc_ptr loop )
1200{
1201 loop->markverts();
1202
1203 Arc_ptr extrema[4];
1204 loop->getextrema( extrema );
1205
1206 unsigned int npts = loop->numpts();
1207 TrimRegion::init( npts, extrema[0] );
1208
1209 Mesher::init( npts );
1210
1211 long ulines = uarray.init( du, extrema[1], extrema[3] );
1212//printf("ulines = %i\n", ulines);
1213 Varray varray;
1214 long vlines = varray.init( dv, extrema[0], extrema[2] );
1215//printf("vlines = %i\n", vlines);
1216 long botv = 0;
1217 long topv;
1218 TrimRegion::init( varray.varray[botv] );
1219 getGridExtent( &extrema[0]->pwlArc->pts[0], &extrema[0]->pwlArc->pts[0] );
1220
1221 for( long quad=0; quad<varray.numquads; quad++ ) {
1222 backend.surfgrid( uarray.uarray[0],
1223 uarray.uarray[ulines-1],
1224 ulines-1,
1225 varray.vval[quad],
1226 varray.vval[quad+1],
1227 varray.voffset[quad+1] - varray.voffset[quad] );
1228
1229 for( long i=varray.voffset[quad]+1; i <= varray.voffset[quad+1]; i++ ) {
1230 topv = botv++;
1231 advance( topv - varray.voffset[quad],
1232 botv - varray.voffset[quad],
1233 varray.varray[botv] );
1234 if( i == vlines )
1235 getPts( extrema[2] );
1236 else
1237 getPts( backend );
1238 getGridExtent();
1239 if( isolines ) {
1240 outline();
1241 } else {
1242 if( canTile() )
1243 coveAndTile();
1244 else
1245 mesh();
1246 }
1247 }
1248 }
1249}
1250
1251
1252void
1253Slicer::outline( void )
1254{
1255 GridTrimVertex upper, lower;
1256 Hull::init( );
1257
1258 backend.bgnoutline();
1259 while( (nextupper( &upper )) ) {
1260 if( upper.isGridVert() )
1261 backend.linevert( upper.g );
1262 else
1263 backend.linevert( upper.t );
1264 }
1265 backend.endoutline();
1266
1267 backend.bgnoutline();
1268 while( (nextlower( &lower )) ) {
1269 if( lower.isGridVert() )
1270 backend.linevert( lower.g );
1271 else
1272 backend.linevert( lower.t );
1273 }
1274 backend.endoutline();
1275}
1276
1277
1278void
1279Slicer::outline( Arc_ptr jarc )
1280{
1281 jarc->markverts();
1282
1283 if( jarc->pwlArc->npts >= 2 ) {
1284 backend.bgnoutline();
1285 for( int j = jarc->pwlArc->npts-1; j >= 0; j-- )
1286 backend.linevert( &(jarc->pwlArc->pts[j]) );
1287 backend.endoutline();
1288 }
1289}
1290
1291
Note: See TracBrowser for help on using the repository browser.