Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

464 lines
10 KiB

  1. /**************************************************************************
  2. * *
  3. * Copyright (C) 1992, Silicon Graphics, Inc. *
  4. * *
  5. * These coded instructions, statements, and computer programs contain *
  6. * unpublished proprietary information of Silicon Graphics, Inc., and *
  7. * are protected by Federal copyright law. They may not be disclosed *
  8. * to third parties or copied or duplicated in any form, in whole or *
  9. * in part, without the prior written consent of Silicon Graphics, Inc. *
  10. * *
  11. **************************************************************************/
  12. /*
  13. * mesher.c++ - $Revision: 1.2 $
  14. * Derrick Burns - 1991
  15. */
  16. #include "glimport.h"
  17. #include "myassert.h"
  18. #include "mystdio.h"
  19. #include "mesher.h"
  20. #include "gridvert.h"
  21. #include "gridtrim.h"
  22. #include "jarcloc.h"
  23. #include "gridline.h"
  24. #include "trimline.h"
  25. #include "uarray.h"
  26. #include "backend.h"
  27. const float Mesher::ZERO = 0.0;
  28. Mesher::Mesher( Backend& b )
  29. : backend( b ),
  30. p( sizeof( GridTrimVertex ), 100, "GridTrimVertexPool" )
  31. {
  32. stacksize = 0;
  33. vdata = 0;
  34. lastedge = 0; //needed to prevent purify UMR
  35. }
  36. Mesher::~Mesher( void )
  37. {
  38. if( vdata ) delete[] vdata;
  39. }
  40. void
  41. Mesher::init( unsigned int npts )
  42. {
  43. p.clear();
  44. if( stacksize < npts ) {
  45. stacksize = 2 * npts;
  46. if( vdata ) delete[] vdata;
  47. vdata = new GridTrimVertex_p[stacksize];
  48. }
  49. }
  50. inline void
  51. Mesher::push( GridTrimVertex *gt )
  52. {
  53. assert( itop+1 != stacksize );
  54. vdata[++itop] = gt;
  55. }
  56. inline void
  57. Mesher::pop( long )
  58. {
  59. }
  60. inline void
  61. Mesher::openMesh()
  62. {
  63. backend.bgntmesh( "addedge" );
  64. }
  65. inline void
  66. Mesher::closeMesh()
  67. {
  68. backend.endtmesh();
  69. }
  70. inline void
  71. Mesher::swapMesh()
  72. {
  73. backend.swaptmesh();
  74. }
  75. inline void
  76. Mesher::clearStack()
  77. {
  78. itop = -1;
  79. last[0] = 0;
  80. }
  81. void
  82. Mesher::finishLower( GridTrimVertex *gtlower )
  83. {
  84. for( push(gtlower);
  85. nextlower( gtlower=new(p) GridTrimVertex );
  86. push(gtlower) )
  87. addLower();
  88. addLast();
  89. }
  90. void
  91. Mesher::finishUpper( GridTrimVertex *gtupper )
  92. {
  93. for( push(gtupper);
  94. nextupper( gtupper=new(p) GridTrimVertex );
  95. push(gtupper) )
  96. addUpper();
  97. addLast();
  98. }
  99. void
  100. Mesher::mesh( void )
  101. {
  102. GridTrimVertex *gtlower, *gtupper;
  103. Hull::init( );
  104. nextupper( gtupper = new(p) GridTrimVertex );
  105. nextlower( gtlower = new(p) GridTrimVertex );
  106. clearStack();
  107. openMesh();
  108. push(gtupper);
  109. nextupper( gtupper = new(p) GridTrimVertex );
  110. nextlower( gtlower );
  111. assert( gtupper->t && gtlower->t );
  112. if( gtupper->t->param[0] < gtlower->t->param[0] ) {
  113. push(gtupper);
  114. lastedge = 1;
  115. if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) {
  116. finishLower(gtlower);
  117. return;
  118. }
  119. } else if( gtupper->t->param[0] > gtlower->t->param[0] ) {
  120. push(gtlower);
  121. lastedge = 0;
  122. if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
  123. finishUpper(gtupper);
  124. return;
  125. }
  126. } else {
  127. if( lastedge == 0 ) {
  128. push(gtupper);
  129. lastedge = 1;
  130. if( nextupper(gtupper=new(p) GridTrimVertex) == 0 ) {
  131. finishLower(gtlower);
  132. return;
  133. }
  134. } else {
  135. push(gtlower);
  136. lastedge = 0;
  137. if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
  138. finishUpper(gtupper);
  139. return;
  140. }
  141. }
  142. }
  143. while ( 1 ) {
  144. if( gtupper->t->param[0] < gtlower->t->param[0] ) {
  145. push(gtupper);
  146. addUpper();
  147. if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) {
  148. finishLower(gtlower);
  149. return;
  150. }
  151. } else if( gtupper->t->param[0] > gtlower->t->param[0] ) {
  152. push(gtlower);
  153. addLower();
  154. if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
  155. finishUpper(gtupper);
  156. return;
  157. }
  158. } else {
  159. if( lastedge == 0 ) {
  160. push(gtupper);
  161. addUpper();
  162. if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) {
  163. finishLower(gtlower);
  164. return;
  165. }
  166. } else {
  167. push(gtlower);
  168. addLower();
  169. if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
  170. finishUpper(gtupper);
  171. return;
  172. }
  173. }
  174. }
  175. }
  176. }
  177. inline int
  178. Mesher::isCcw( int ilast )
  179. {
  180. REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t );
  181. return (area < ZERO) ? 0 : 1;
  182. }
  183. inline int
  184. Mesher::isCw( int ilast )
  185. {
  186. REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t );
  187. return (area > -ZERO) ? 0 : 1;
  188. }
  189. inline int
  190. Mesher::equal( int x, int y )
  191. {
  192. return( last[0] == vdata[x] && last[1] == vdata[y] );
  193. }
  194. inline void
  195. Mesher::copy( int x, int y )
  196. {
  197. last[0] = vdata[x]; last[1] = vdata[y];
  198. }
  199. inline void
  200. Mesher::move( int x, int y )
  201. {
  202. vdata[x] = vdata[y];
  203. }
  204. inline void
  205. Mesher::output( int x )
  206. {
  207. backend.tmeshvert( vdata[x] );
  208. }
  209. /*---------------------------------------------------------------------------
  210. * addedge - addedge an edge to the triangulation
  211. *
  212. * This code has been re-written to generate large triangle meshes
  213. * from a monotone polygon. Although smaller triangle meshes
  214. * could be generated faster and with less code, larger meshes
  215. * actually give better SYSTEM performance. This is because
  216. * vertices are processed in the backend slower than they are
  217. * generated by this code and any decrease in the number of vertices
  218. * results in a decrease in the time spent in the backend.
  219. *---------------------------------------------------------------------------
  220. */
  221. void
  222. Mesher::addLast( )
  223. {
  224. register int ilast = itop;
  225. if( lastedge == 0 ) {
  226. if( equal( 0, 1 ) ) {
  227. output( ilast );
  228. swapMesh();
  229. for( register int i = 2; i < ilast; i++ ) {
  230. swapMesh();
  231. output( i );
  232. }
  233. copy( ilast, ilast-1 );
  234. } else if( equal( ilast-2, ilast-1) ) {
  235. swapMesh();
  236. output( ilast );
  237. for( register int i = ilast-3; i >= 0; i-- ) {
  238. output( i );
  239. swapMesh();
  240. }
  241. copy( 0, ilast );
  242. } else {
  243. closeMesh(); openMesh();
  244. output( ilast );
  245. output( 0 );
  246. for( register int i = 1; i < ilast; i++ ) {
  247. swapMesh();
  248. output( i );
  249. }
  250. copy( ilast, ilast-1 );
  251. }
  252. } else {
  253. if( equal( 1, 0) ) {
  254. swapMesh();
  255. output( ilast );
  256. for( register int i = 2; i < ilast; i++ ) {
  257. output( i );
  258. swapMesh();
  259. }
  260. copy( ilast-1, ilast );
  261. } else if( equal( ilast-1, ilast-2) ) {
  262. output( ilast );
  263. swapMesh();
  264. for( register int i = ilast-3; i >= 0; i-- ) {
  265. swapMesh();
  266. output( i );
  267. }
  268. copy( ilast, 0 );
  269. } else {
  270. closeMesh(); openMesh();
  271. output( 0 );
  272. output( ilast );
  273. for( register int i = 1; i < ilast; i++ ) {
  274. output( i );
  275. swapMesh();
  276. }
  277. copy( ilast-1, ilast );
  278. }
  279. }
  280. closeMesh();
  281. //for( register long k=0; k<=ilast; k++ ) pop( k );
  282. }
  283. void
  284. Mesher::addUpper( )
  285. {
  286. register int ilast = itop;
  287. if( lastedge == 0 ) {
  288. if( equal( 0, 1 ) ) {
  289. output( ilast );
  290. swapMesh();
  291. for( register int i = 2; i < ilast; i++ ) {
  292. swapMesh();
  293. output( i );
  294. }
  295. copy( ilast, ilast-1 );
  296. } else if( equal( ilast-2, ilast-1) ) {
  297. swapMesh();
  298. output( ilast );
  299. for( register int i = ilast-3; i >= 0; i-- ) {
  300. output( i );
  301. swapMesh();
  302. }
  303. copy( 0, ilast );
  304. } else {
  305. closeMesh(); openMesh();
  306. output( ilast );
  307. output( 0 );
  308. for( register int i = 1; i < ilast; i++ ) {
  309. swapMesh();
  310. output( i );
  311. }
  312. copy( ilast, ilast-1 );
  313. }
  314. lastedge = 1;
  315. //for( register long k=0; k<ilast-1; k++ ) pop( k );
  316. move( 0, ilast-1 );
  317. move( 1, ilast );
  318. itop = 1;
  319. } else {
  320. if( ! isCcw( ilast ) ) return;
  321. do {
  322. itop--;
  323. } while( (itop > 1) && isCcw( ilast ) );
  324. if( equal( ilast-1, ilast-2 ) ) {
  325. output( ilast );
  326. swapMesh();
  327. for( register int i=ilast-3; i>=itop-1; i-- ) {
  328. swapMesh();
  329. output( i );
  330. }
  331. copy( ilast, itop-1 );
  332. } else if( equal( itop, itop-1 ) ) {
  333. swapMesh();
  334. output( ilast );
  335. for( register int i = itop+1; i < ilast; i++ ) {
  336. output( i );
  337. swapMesh();
  338. }
  339. copy( ilast-1, ilast );
  340. } else {
  341. closeMesh(); openMesh();
  342. output( ilast );
  343. output( ilast-1 );
  344. for( register int i=ilast-2; i>=itop-1; i-- ) {
  345. swapMesh();
  346. output( i );
  347. }
  348. copy( ilast, itop-1 );
  349. }
  350. //for( register int k=itop; k<ilast; k++ ) pop( k );
  351. move( itop, ilast );
  352. }
  353. }
  354. void
  355. Mesher::addLower()
  356. {
  357. register int ilast = itop;
  358. if( lastedge == 1 ) {
  359. if( equal( 1, 0) ) {
  360. swapMesh();
  361. output( ilast );
  362. for( register int i = 2; i < ilast; i++ ) {
  363. output( i );
  364. swapMesh();
  365. }
  366. copy( ilast-1, ilast );
  367. } else if( equal( ilast-1, ilast-2) ) {
  368. output( ilast );
  369. swapMesh();
  370. for( register int i = ilast-3; i >= 0; i-- ) {
  371. swapMesh();
  372. output( i );
  373. }
  374. copy( ilast, 0 );
  375. } else {
  376. closeMesh(); openMesh();
  377. output( 0 );
  378. output( ilast );
  379. for( register int i = 1; i < ilast; i++ ) {
  380. output( i );
  381. swapMesh();
  382. }
  383. copy( ilast-1, ilast );
  384. }
  385. lastedge = 0;
  386. //for( register long k=0; k<ilast-1; k++ ) pop( k );
  387. move( 0, ilast-1 );
  388. move( 1, ilast );
  389. itop = 1;
  390. } else {
  391. if( ! isCw( ilast ) ) return;
  392. do {
  393. itop--;
  394. } while( (itop > 1) && isCw( ilast ) );
  395. if( equal( ilast-2, ilast-1) ) {
  396. swapMesh();
  397. output( ilast );
  398. for( register int i=ilast-3; i>=itop-1; i--) {
  399. output( i );
  400. swapMesh( );
  401. }
  402. copy( itop-1, ilast );
  403. } else if( equal( itop-1, itop) ) {
  404. output( ilast );
  405. swapMesh();
  406. for( register int i=itop+1; i<ilast; i++ ) {
  407. swapMesh( );
  408. output( i );
  409. }
  410. copy( ilast, ilast-1 );
  411. } else {
  412. closeMesh(); openMesh();
  413. output( ilast-1 );
  414. output( ilast );
  415. for( register int i=ilast-2; i>=itop-1; i-- ) {
  416. output( i );
  417. swapMesh( );
  418. }
  419. copy( itop-1, ilast );
  420. }
  421. //for( register int k=itop; k<ilast; k++ ) pop( k );
  422. move( itop, ilast );
  423. }
  424. }