render.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. /*
  2. * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
  3. * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. * and/or sell copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice including the dates of first publication and
  13. * either this permission notice or a reference to
  14. * http://oss.sgi.com/projects/FreeB/
  15. * shall be included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
  22. * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE.
  24. *
  25. * Except as contained in this notice, the name of Silicon Graphics, Inc.
  26. * shall not be used in advertising or otherwise to promote the sale, use or
  27. * other dealings in this Software without prior written authorization from
  28. * Silicon Graphics, Inc.
  29. */
  30. /*
  31. ** Author: Eric Veach, July 1994.
  32. **
  33. */
  34. #include "gluos.h"
  35. #include <assert.h>
  36. #include <stddef.h>
  37. #include "mesh.h"
  38. #include "tess.h"
  39. #include "render.h"
  40. #ifndef TRUE
  41. #define TRUE 1
  42. #endif
  43. #ifndef FALSE
  44. #define FALSE 0
  45. #endif
  46. /* This structure remembers the information we need about a primitive
  47. * to be able to render it later, once we have determined which
  48. * primitive is able to use the most triangles.
  49. */
  50. struct FaceCount {
  51. long size; /* number of triangles used */
  52. GLUhalfEdge *eStart; /* edge where this primitive starts */
  53. void (*render)(GLUtesselator *, GLUhalfEdge *, long);
  54. /* routine to render this primitive */
  55. };
  56. static struct FaceCount MaximumFan( GLUhalfEdge *eOrig );
  57. static struct FaceCount MaximumStrip( GLUhalfEdge *eOrig );
  58. static void RenderFan( GLUtesselator *tess, GLUhalfEdge *eStart, long size );
  59. static void RenderStrip( GLUtesselator *tess, GLUhalfEdge *eStart, long size );
  60. static void RenderTriangle( GLUtesselator *tess, GLUhalfEdge *eStart,
  61. long size );
  62. static void RenderMaximumFaceGroup( GLUtesselator *tess, GLUface *fOrig );
  63. static void RenderLonelyTriangles( GLUtesselator *tess, GLUface *head );
  64. /************************ Strips and Fans decomposition ******************/
  65. /* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle
  66. * fans, strips, and separate triangles. A substantial effort is made
  67. * to use as few rendering primitives as possible (ie. to make the fans
  68. * and strips as large as possible).
  69. *
  70. * The rendering output is provided as callbacks (see the api).
  71. */
  72. void __gl_renderMesh( GLUtesselator *tess, GLUmesh *mesh )
  73. {
  74. GLUface *f;
  75. /* Make a list of separate triangles so we can render them all at once */
  76. tess->lonelyTriList = NULL;
  77. for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
  78. f->marked = FALSE;
  79. }
  80. for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
  81. /* We examine all faces in an arbitrary order. Whenever we find
  82. * an unprocessed face F, we output a group of faces including F
  83. * whose size is maximum.
  84. */
  85. if( f->inside && ! f->marked ) {
  86. RenderMaximumFaceGroup( tess, f );
  87. assert( f->marked );
  88. }
  89. }
  90. if( tess->lonelyTriList != NULL ) {
  91. RenderLonelyTriangles( tess, tess->lonelyTriList );
  92. tess->lonelyTriList = NULL;
  93. }
  94. }
  95. static void RenderMaximumFaceGroup( GLUtesselator *tess, GLUface *fOrig )
  96. {
  97. /* We want to find the largest triangle fan or strip of unmarked faces
  98. * which includes the given face fOrig. There are 3 possible fans
  99. * passing through fOrig (one centered at each vertex), and 3 possible
  100. * strips (one for each CCW permutation of the vertices). Our strategy
  101. * is to try all of these, and take the primitive which uses the most
  102. * triangles (a greedy approach).
  103. */
  104. GLUhalfEdge *e = fOrig->anEdge;
  105. struct FaceCount max, newFace;
  106. max.size = 1;
  107. max.eStart = e;
  108. max.render = &RenderTriangle;
  109. if( ! tess->flagBoundary ) {
  110. newFace = MaximumFan( e ); if( newFace.size > max.size ) { max = newFace; }
  111. newFace = MaximumFan( e->Lnext ); if( newFace.size > max.size ) { max = newFace; }
  112. newFace = MaximumFan( e->Lprev ); if( newFace.size > max.size ) { max = newFace; }
  113. newFace = MaximumStrip( e ); if( newFace.size > max.size ) { max = newFace; }
  114. newFace = MaximumStrip( e->Lnext ); if( newFace.size > max.size ) { max = newFace; }
  115. newFace = MaximumStrip( e->Lprev ); if( newFace.size > max.size ) { max = newFace; }
  116. }
  117. (*(max.render))( tess, max.eStart, max.size );
  118. }
  119. /* Macros which keep track of faces we have marked temporarily, and allow
  120. * us to backtrack when necessary. With triangle fans, this is not
  121. * really necessary, since the only awkward case is a loop of triangles
  122. * around a single origin vertex. However with strips the situation is
  123. * more complicated, and we need a general tracking method like the
  124. * one here.
  125. */
  126. #define Marked(f) (! (f)->inside || (f)->marked)
  127. #define AddToTrail(f,t) ((f)->trail = (t), (t) = (f), (f)->marked = TRUE)
  128. #define FreeTrail(t) do { \
  129. while( (t) != NULL ) { \
  130. (t)->marked = FALSE; t = (t)->trail; \
  131. } \
  132. } while(0) /* absorb trailing semicolon */
  133. static struct FaceCount MaximumFan( GLUhalfEdge *eOrig )
  134. {
  135. /* eOrig->Lface is the face we want to render. We want to find the size
  136. * of a maximal fan around eOrig->Org. To do this we just walk around
  137. * the origin vertex as far as possible in both directions.
  138. */
  139. struct FaceCount newFace = { 0, NULL, &RenderFan };
  140. GLUface *trail = NULL;
  141. GLUhalfEdge *e;
  142. for( e = eOrig; ! Marked( e->Lface ); e = e->Onext ) {
  143. AddToTrail( e->Lface, trail );
  144. ++newFace.size;
  145. }
  146. for( e = eOrig; ! Marked( e->Rface ); e = e->Oprev ) {
  147. AddToTrail( e->Rface, trail );
  148. ++newFace.size;
  149. }
  150. newFace.eStart = e;
  151. /*LINTED*/
  152. FreeTrail( trail );
  153. return newFace;
  154. }
  155. #define IsEven(n) (((n) & 1) == 0)
  156. static struct FaceCount MaximumStrip( GLUhalfEdge *eOrig )
  157. {
  158. /* Here we are looking for a maximal strip that contains the vertices
  159. * eOrig->Org, eOrig->Dst, eOrig->Lnext->Dst (in that order or the
  160. * reverse, such that all triangles are oriented CCW).
  161. *
  162. * Again we walk forward and backward as far as possible. However for
  163. * strips there is a twist: to get CCW orientations, there must be
  164. * an *even* number of triangles in the strip on one side of eOrig.
  165. * We walk the strip starting on a side with an even number of triangles;
  166. * if both side have an odd number, we are forced to shorten one side.
  167. */
  168. struct FaceCount newFace = { 0, NULL, &RenderStrip };
  169. long headSize = 0, tailSize = 0;
  170. GLUface *trail = NULL;
  171. GLUhalfEdge *e, *eTail, *eHead;
  172. for( e = eOrig; ! Marked( e->Lface ); ++tailSize, e = e->Onext ) {
  173. AddToTrail( e->Lface, trail );
  174. ++tailSize;
  175. e = e->Dprev;
  176. if( Marked( e->Lface )) break;
  177. AddToTrail( e->Lface, trail );
  178. }
  179. eTail = e;
  180. for( e = eOrig; ! Marked( e->Rface ); ++headSize, e = e->Dnext ) {
  181. AddToTrail( e->Rface, trail );
  182. ++headSize;
  183. e = e->Oprev;
  184. if( Marked( e->Rface )) break;
  185. AddToTrail( e->Rface, trail );
  186. }
  187. eHead = e;
  188. newFace.size = tailSize + headSize;
  189. if( IsEven( tailSize )) {
  190. newFace.eStart = eTail->Sym;
  191. } else if( IsEven( headSize )) {
  192. newFace.eStart = eHead;
  193. } else {
  194. /* Both sides have odd length, we must shorten one of them. In fact,
  195. * we must start from eHead to guarantee inclusion of eOrig->Lface.
  196. */
  197. --newFace.size;
  198. newFace.eStart = eHead->Onext;
  199. }
  200. /*LINTED*/
  201. FreeTrail( trail );
  202. return newFace;
  203. }
  204. static void RenderTriangle( GLUtesselator *tess, GLUhalfEdge *e, long size )
  205. {
  206. /* Just add the triangle to a triangle list, so we can render all
  207. * the separate triangles at once.
  208. */
  209. assert( size == 1 );
  210. AddToTrail( e->Lface, tess->lonelyTriList );
  211. }
  212. static void RenderLonelyTriangles( GLUtesselator *tess, GLUface *f )
  213. {
  214. /* Now we render all the separate triangles which could not be
  215. * grouped into a triangle fan or strip.
  216. */
  217. GLUhalfEdge *e;
  218. int newState;
  219. int edgeState = -1; /* force edge state output for first vertex */
  220. CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLES );
  221. for( ; f != NULL; f = f->trail ) {
  222. /* Loop once for each edge (there will always be 3 edges) */
  223. e = f->anEdge;
  224. do {
  225. if( tess->flagBoundary ) {
  226. /* Set the "edge state" to TRUE just before we output the
  227. * first vertex of each edge on the polygon boundary.
  228. */
  229. newState = ! e->Rface->inside;
  230. if( edgeState != newState ) {
  231. edgeState = newState;
  232. CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA( edgeState );
  233. }
  234. }
  235. CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
  236. e = e->Lnext;
  237. } while( e != f->anEdge );
  238. }
  239. CALL_END_OR_END_DATA();
  240. }
  241. static void RenderFan( GLUtesselator *tess, GLUhalfEdge *e, long size )
  242. {
  243. /* Render as many CCW triangles as possible in a fan starting from
  244. * edge "e". The fan *should* contain exactly "size" triangles
  245. * (otherwise we've goofed up somewhere).
  246. */
  247. CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLE_FAN );
  248. CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
  249. CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
  250. while( ! Marked( e->Lface )) {
  251. e->Lface->marked = TRUE;
  252. --size;
  253. e = e->Onext;
  254. CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
  255. }
  256. assert( size == 0 );
  257. CALL_END_OR_END_DATA();
  258. }
  259. static void RenderStrip( GLUtesselator *tess, GLUhalfEdge *e, long size )
  260. {
  261. /* Render as many CCW triangles as possible in a strip starting from
  262. * edge "e". The strip *should* contain exactly "size" triangles
  263. * (otherwise we've goofed up somewhere).
  264. */
  265. CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLE_STRIP );
  266. CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
  267. CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
  268. while( ! Marked( e->Lface )) {
  269. e->Lface->marked = TRUE;
  270. --size;
  271. e = e->Dprev;
  272. CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
  273. if( Marked( e->Lface )) break;
  274. e->Lface->marked = TRUE;
  275. --size;
  276. e = e->Onext;
  277. CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
  278. }
  279. assert( size == 0 );
  280. CALL_END_OR_END_DATA();
  281. }
  282. /************************ Boundary contour decomposition ******************/
  283. /* __gl_renderBoundary( tess, mesh ) takes a mesh, and outputs one
  284. * contour for each face marked "inside". The rendering output is
  285. * provided as callbacks (see the api).
  286. */
  287. void __gl_renderBoundary( GLUtesselator *tess, GLUmesh *mesh )
  288. {
  289. GLUface *f;
  290. GLUhalfEdge *e;
  291. for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
  292. if( f->inside ) {
  293. CALL_BEGIN_OR_BEGIN_DATA( GL_LINE_LOOP );
  294. e = f->anEdge;
  295. do {
  296. CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
  297. e = e->Lnext;
  298. } while( e != f->anEdge );
  299. CALL_END_OR_END_DATA();
  300. }
  301. }
  302. }
  303. /************************ Quick-and-dirty decomposition ******************/
  304. #define SIGN_INCONSISTENT 2
  305. static int ComputeNormal( GLUtesselator *tess, GLdouble norm[3], int check )
  306. /*
  307. * If check==FALSE, we compute the polygon normal and place it in norm[].
  308. * If check==TRUE, we check that each triangle in the fan from v0 has a
  309. * consistent orientation with respect to norm[]. If triangles are
  310. * consistently oriented CCW, return 1; if CW, return -1; if all triangles
  311. * are degenerate return 0; otherwise (no consistent orientation) return
  312. * SIGN_INCONSISTENT.
  313. */
  314. {
  315. CachedVertex *v0 = tess->cache;
  316. CachedVertex *vn = v0 + tess->cacheCount;
  317. CachedVertex *vc;
  318. GLdouble dot, xc, yc, zc, xp, yp, zp, n[3];
  319. int sign = 0;
  320. /* Find the polygon normal. It is important to get a reasonable
  321. * normal even when the polygon is self-intersecting (eg. a bowtie).
  322. * Otherwise, the computed normal could be very tiny, but perpendicular
  323. * to the true plane of the polygon due to numerical noise. Then all
  324. * the triangles would appear to be degenerate and we would incorrectly
  325. * decompose the polygon as a fan (or simply not render it at all).
  326. *
  327. * We use a sum-of-triangles normal algorithm rather than the more
  328. * efficient sum-of-trapezoids method (used in CheckOrientation()
  329. * in normal.c). This lets us explicitly reverse the signed area
  330. * of some triangles to get a reasonable normal in the self-intersecting
  331. * case.
  332. */
  333. if( ! check ) {
  334. norm[0] = norm[1] = norm[2] = 0.0;
  335. }
  336. vc = v0 + 1;
  337. xc = vc->coords[0] - v0->coords[0];
  338. yc = vc->coords[1] - v0->coords[1];
  339. zc = vc->coords[2] - v0->coords[2];
  340. while( ++vc < vn ) {
  341. xp = xc; yp = yc; zp = zc;
  342. xc = vc->coords[0] - v0->coords[0];
  343. yc = vc->coords[1] - v0->coords[1];
  344. zc = vc->coords[2] - v0->coords[2];
  345. /* Compute (vp - v0) cross (vc - v0) */
  346. n[0] = yp*zc - zp*yc;
  347. n[1] = zp*xc - xp*zc;
  348. n[2] = xp*yc - yp*xc;
  349. dot = n[0]*norm[0] + n[1]*norm[1] + n[2]*norm[2];
  350. if( ! check ) {
  351. /* Reverse the contribution of back-facing triangles to get
  352. * a reasonable normal for self-intersecting polygons (see above)
  353. */
  354. if( dot >= 0 ) {
  355. norm[0] += n[0]; norm[1] += n[1]; norm[2] += n[2];
  356. } else {
  357. norm[0] -= n[0]; norm[1] -= n[1]; norm[2] -= n[2];
  358. }
  359. } else if( dot != 0 ) {
  360. /* Check the new orientation for consistency with previous triangles */
  361. if( dot > 0 ) {
  362. if( sign < 0 ) return SIGN_INCONSISTENT;
  363. sign = 1;
  364. } else {
  365. if( sign > 0 ) return SIGN_INCONSISTENT;
  366. sign = -1;
  367. }
  368. }
  369. }
  370. return sign;
  371. }
  372. /* __gl_renderCache( tess ) takes a single contour and tries to render it
  373. * as a triangle fan. This handles convex polygons, as well as some
  374. * non-convex polygons if we get lucky.
  375. *
  376. * Returns TRUE if the polygon was successfully rendered. The rendering
  377. * output is provided as callbacks (see the api).
  378. */
  379. GLboolean __gl_renderCache( GLUtesselator *tess )
  380. {
  381. CachedVertex *v0 = tess->cache;
  382. CachedVertex *vn = v0 + tess->cacheCount;
  383. CachedVertex *vc;
  384. GLdouble norm[3];
  385. int sign;
  386. if( tess->cacheCount < 3 ) {
  387. /* Degenerate contour -- no output */
  388. return TRUE;
  389. }
  390. norm[0] = tess->normal[0];
  391. norm[1] = tess->normal[1];
  392. norm[2] = tess->normal[2];
  393. if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) {
  394. ComputeNormal( tess, norm, FALSE );
  395. }
  396. sign = ComputeNormal( tess, norm, TRUE );
  397. if( sign == SIGN_INCONSISTENT ) {
  398. /* Fan triangles did not have a consistent orientation */
  399. return FALSE;
  400. }
  401. if( sign == 0 ) {
  402. /* All triangles were degenerate */
  403. return TRUE;
  404. }
  405. /* Make sure we do the right thing for each winding rule */
  406. switch( tess->windingRule ) {
  407. case GLU_TESS_WINDING_ODD:
  408. case GLU_TESS_WINDING_NONZERO:
  409. break;
  410. case GLU_TESS_WINDING_POSITIVE:
  411. if( sign < 0 ) return TRUE;
  412. break;
  413. case GLU_TESS_WINDING_NEGATIVE:
  414. if( sign > 0 ) return TRUE;
  415. break;
  416. case GLU_TESS_WINDING_ABS_GEQ_TWO:
  417. return TRUE;
  418. }
  419. CALL_BEGIN_OR_BEGIN_DATA( tess->boundaryOnly ? GL_LINE_LOOP
  420. : (tess->cacheCount > 3) ? GL_TRIANGLE_FAN
  421. : GL_TRIANGLES );
  422. CALL_VERTEX_OR_VERTEX_DATA( v0->data );
  423. if( sign > 0 ) {
  424. for( vc = v0+1; vc < vn; ++vc ) {
  425. CALL_VERTEX_OR_VERTEX_DATA( vc->data );
  426. }
  427. } else {
  428. for( vc = vn-1; vc > v0; --vc ) {
  429. CALL_VERTEX_OR_VERTEX_DATA( vc->data );
  430. }
  431. }
  432. CALL_END_OR_END_DATA();
  433. return TRUE;
  434. }