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.

570 lines
14 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. * intersect.c++ - $Revision: 1.5 $
  14. * Derrick Burns - 1991
  15. */
  16. #include "glimport.h"
  17. #include "myassert.h"
  18. #include "mystdio.h"
  19. #include "subdivid.h"
  20. #include "arc.h"
  21. #include "bin.h"
  22. #include "backend.h"
  23. #include "trimpool.h"
  24. enum i_result { INTERSECT_VERTEX, INTERSECT_EDGE };
  25. /* local functions */
  26. static int arc_classify( Arc_ptr, int, REAL );
  27. static enum i_result pwlarc_intersect( PwlArc *, int, REAL, int, int[3] );
  28. void
  29. Subdivider::partition( Bin & bin, Bin & left, Bin & intersections,
  30. Bin & right, Bin & unknown, int param, REAL value )
  31. {
  32. Bin headonleft, headonright, tailonleft, tailonright;
  33. for( Arc_ptr jarc = bin.removearc(); jarc; jarc = bin.removearc() ) {
  34. REAL tdiff = jarc->tail()[param] - value;
  35. REAL hdiff = jarc->head()[param] - value;
  36. if( tdiff > 0.0 ) {
  37. if( hdiff > 0.0 ) {
  38. right.addarc( jarc );
  39. } else if( hdiff == 0.0 ) {
  40. tailonright.addarc( jarc );
  41. } else {
  42. Arc_ptr jtemp;
  43. switch( arc_split(jarc, param, value, 0) ) {
  44. case 2:
  45. tailonright.addarc( jarc );
  46. headonleft.addarc( jarc->next );
  47. break;
  48. case 31:
  49. assert( jarc->head()[param] > value );
  50. right.addarc( jarc );
  51. tailonright.addarc( jtemp = jarc->next );
  52. headonleft.addarc( jtemp->next );
  53. break;
  54. case 32:
  55. assert( jarc->head()[param] <= value );
  56. tailonright .addarc( jarc );
  57. headonleft.addarc( jtemp = jarc->next );
  58. left.addarc( jtemp->next );
  59. break;
  60. case 4:
  61. right.addarc( jarc );
  62. tailonright.addarc( jtemp = jarc->next );
  63. headonleft.addarc( jtemp = jtemp->next );
  64. left.addarc( jtemp->next );
  65. }
  66. }
  67. } else if( tdiff == 0.0 ) {
  68. if( hdiff > 0.0 ) {
  69. headonright.addarc( jarc );
  70. } else if( hdiff == 0.0 ) {
  71. unknown.addarc( jarc );
  72. } else {
  73. headonleft.addarc( jarc );
  74. }
  75. } else {
  76. if( hdiff > 0.0 ) {
  77. Arc_ptr jtemp;
  78. switch( arc_split(jarc, param, value, 1) ) {
  79. case 2:
  80. tailonleft.addarc( jarc );
  81. headonright.addarc( jarc->next );
  82. break;
  83. case 31:
  84. assert( jarc->head()[param] < value );
  85. left.addarc( jarc );
  86. tailonleft.addarc( jtemp = jarc->next );
  87. headonright.addarc( jtemp->next );
  88. break;
  89. case 32:
  90. assert( jarc->head()[param] >= value );
  91. tailonleft.addarc( jarc );
  92. headonright.addarc( jtemp = jarc->next );
  93. right.addarc( jtemp->next );
  94. break;
  95. case 4:
  96. left.addarc( jarc );
  97. tailonleft.addarc( jtemp = jarc->next );
  98. headonright.addarc( jtemp = jtemp->next );
  99. right.addarc( jtemp->next );
  100. }
  101. } else if( hdiff == 0.0 ) {
  102. tailonleft.addarc( jarc );
  103. } else {
  104. left.addarc( jarc );
  105. }
  106. }
  107. }
  108. if( param == 0 ) {
  109. classify_headonleft_s( headonleft, intersections, left, value );
  110. classify_tailonleft_s( tailonleft, intersections, left, value );
  111. classify_headonright_s( headonright, intersections, right, value );
  112. classify_tailonright_s( tailonright, intersections, right, value );
  113. } else {
  114. classify_headonleft_t( headonleft, intersections, left, value );
  115. classify_tailonleft_t( tailonleft, intersections, left, value );
  116. classify_headonright_t( headonright, intersections, right, value );
  117. classify_tailonright_t( tailonright, intersections, right, value );
  118. }
  119. }
  120. inline static void
  121. vert_interp( TrimVertex *n, TrimVertex *l, TrimVertex *r, int p, REAL val )
  122. {
  123. assert( val > l->param[p]);
  124. assert( val < r->param[p]);
  125. n->nuid = l->nuid;
  126. n->param[p] = val;
  127. if( l->param[1-p] != r->param[1-p] ) {
  128. REAL ratio = (val - l->param[p]) / (r->param[p] - l->param[p]);
  129. n->param[1-p] = l->param[1-p] +
  130. ratio * (r->param[1-p] - l->param[1-p]);
  131. } else {
  132. n->param[1-p] = l->param[1-p];
  133. }
  134. }
  135. int
  136. Subdivider::arc_split( Arc_ptr jarc, int param, REAL value, int dir )
  137. {
  138. int maxvertex = jarc->pwlArc->npts;
  139. Arc_ptr jarc1, jarc2, jarc3;
  140. TrimVertex* v = jarc->pwlArc->pts;
  141. int loc[3];
  142. switch( pwlarc_intersect( jarc->pwlArc, param, value, dir, loc ) ) {
  143. case INTERSECT_VERTEX: {
  144. jarc1 = new(arcpool) Arc( jarc, new( pwlarcpool) PwlArc( maxvertex-loc[1], &v[loc[1]] ) );
  145. jarc->pwlArc->npts = loc[1] + 1;
  146. jarc1->next = jarc->next;
  147. jarc1->next->prev = jarc1;
  148. jarc->next = jarc1;
  149. jarc1->prev = jarc;
  150. assert(jarc->check() != 0);
  151. return 2;
  152. }
  153. case INTERSECT_EDGE: {
  154. int i, j;
  155. if( dir == 0 ) {
  156. i = loc[0];
  157. j = loc[2];
  158. } else {
  159. i = loc[2];
  160. j = loc[0];
  161. }
  162. TrimVertex *newjunk = trimvertexpool.get(3);
  163. v[i].nuid = jarc->nuid;
  164. v[j].nuid = jarc->nuid;
  165. newjunk[0] = v[j];
  166. newjunk[2] = v[i];
  167. vert_interp( &newjunk[1], &v[loc[0]], &v[loc[2]], param, value );
  168. if( showingDegenerate() )
  169. backend.triangle( &newjunk[2], &newjunk[1], &newjunk[0] );
  170. if (maxvertex == 2) {
  171. jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) );
  172. jarc->pwlArc->npts = 2;
  173. jarc->pwlArc->pts = newjunk;
  174. jarc1->next = jarc->next;
  175. jarc1->next->prev = jarc1;
  176. jarc->next = jarc1;
  177. jarc1->prev = jarc;
  178. assert(jarc->check() != 0);
  179. return 2;
  180. } else if (maxvertex - j == 2) {
  181. jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk ) );
  182. jarc2 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) );
  183. jarc->pwlArc->npts = maxvertex-1;
  184. jarc2->next = jarc->next;
  185. jarc2->next->prev = jarc2;
  186. jarc->next = jarc1;
  187. jarc1->prev = jarc;
  188. jarc1->next = jarc2;
  189. jarc2->prev = jarc1;
  190. assert(jarc->check() != 0);
  191. return 31;
  192. } else if (i == 1) {
  193. jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) );
  194. jarc2 = new(arcpool) Arc( jarc,
  195. new(pwlarcpool) PwlArc( maxvertex-1, &jarc->pwlArc->pts[1] ) );
  196. jarc->pwlArc->npts = 2;
  197. jarc->pwlArc->pts = newjunk;
  198. jarc2->next = jarc->next;
  199. jarc2->next->prev = jarc2;
  200. jarc->next = jarc1;
  201. jarc1->prev = jarc;
  202. jarc1->next = jarc2;
  203. jarc2->prev = jarc1;
  204. assert(jarc->check() != 0);
  205. return 32;
  206. } else {
  207. jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk ) );
  208. jarc2 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) );
  209. jarc3 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( maxvertex-i, v+i ) );
  210. jarc->pwlArc->npts = j + 1;
  211. jarc3->next = jarc->next;
  212. jarc3->next->prev = jarc3;
  213. jarc->next = jarc1;
  214. jarc1->prev = jarc;
  215. jarc1->next = jarc2;
  216. jarc2->prev = jarc1;
  217. jarc2->next = jarc3;
  218. jarc3->prev = jarc2;
  219. assert(jarc->check() != 0);
  220. return 4;
  221. }
  222. }
  223. default:
  224. return -1; //picked -1 since it's not used
  225. }
  226. }
  227. /*----------------------------------------------------------------------------
  228. * pwlarc_intersect - find intersection of pwlArc and isoparametric line
  229. *----------------------------------------------------------------------------
  230. */
  231. static enum i_result
  232. pwlarc_intersect(
  233. PwlArc *pwlArc,
  234. int param,
  235. REAL value,
  236. int dir,
  237. int loc[3] )
  238. {
  239. assert( pwlArc->npts > 0 );
  240. if( dir ) {
  241. TrimVertex *v = pwlArc->pts;
  242. int imin = 0;
  243. int imax = pwlArc->npts - 1;
  244. assert( value > v[imin].param[param] );
  245. assert( value < v[imax].param[param] );
  246. while( (imax - imin) > 1 ) {
  247. int imid = (imax + imin)/2;
  248. if( v[imid].param[param] > value )
  249. imax = imid;
  250. else if( v[imid].param[param] < value )
  251. imin = imid;
  252. else {
  253. loc[1] = imid;
  254. return INTERSECT_VERTEX;
  255. }
  256. }
  257. loc[0] = imin;
  258. loc[2] = imax;
  259. return INTERSECT_EDGE;
  260. } else {
  261. TrimVertex *v = pwlArc->pts;
  262. int imax = 0;
  263. int imin = pwlArc->npts - 1;
  264. assert( value > v[imin].param[param] );
  265. assert( value < v[imax].param[param] );
  266. while( (imin - imax) > 1 ) {
  267. int imid = (imax + imin)/2;
  268. if( v[imid].param[param] > value )
  269. imax = imid;
  270. else if( v[imid].param[param] < value )
  271. imin = imid;
  272. else {
  273. loc[1] = imid;
  274. return INTERSECT_VERTEX;
  275. }
  276. }
  277. loc[0] = imin;
  278. loc[2] = imax;
  279. return INTERSECT_EDGE;
  280. }
  281. }
  282. /*----------------------------------------------------------------------------
  283. * arc_classify - determine which side of a line a jarc lies
  284. *----------------------------------------------------------------------------
  285. */
  286. static int
  287. arc_classify( Arc_ptr jarc, int param, REAL value )
  288. {
  289. REAL tdiff, hdiff;
  290. if( param == 0 ) {
  291. tdiff = jarc->tail()[0] - value;
  292. hdiff = jarc->head()[0] - value;
  293. } else {
  294. tdiff = jarc->tail()[1] - value;
  295. hdiff = jarc->head()[1] - value;
  296. }
  297. if( tdiff > 0.0 ) {
  298. if( hdiff > 0.0 ) {
  299. return 0x11;
  300. } else if( hdiff == 0.0 ) {
  301. return 0x12;
  302. } else {
  303. return 0x10;
  304. }
  305. } else if( tdiff == 0.0 ) {
  306. if( hdiff > 0.0 ) {
  307. return 0x21;
  308. } else if( hdiff == 0.0 ) {
  309. return 0x22;
  310. } else {
  311. return 0x20;
  312. }
  313. } else {
  314. if( hdiff > 0.0 ) {
  315. return 0x01;
  316. } else if( hdiff == 0.0 ) {
  317. return 0x02;
  318. } else {
  319. return 0;
  320. }
  321. }
  322. }
  323. void
  324. Subdivider::classify_tailonleft_s( Bin& bin, Bin& in, Bin& out, REAL val )
  325. {
  326. /* tail at left, head on line */
  327. Arc_ptr j;
  328. while( j = bin.removearc() ) {
  329. assert( arc_classify( j, 0, val ) == 0x02 );
  330. j->clearitail();
  331. REAL diff = j->next->head()[0] - val;
  332. if( diff > 0.0 ) {
  333. in.addarc( j );
  334. } else if( diff < 0.0 ) {
  335. if( ccwTurn_sl( j, j->next ) )
  336. out.addarc( j );
  337. else
  338. in.addarc( j );
  339. } else {
  340. if( j->next->tail()[1] > j->next->head()[1] )
  341. in.addarc(j);
  342. else
  343. out.addarc(j);
  344. }
  345. }
  346. }
  347. void
  348. Subdivider::classify_tailonleft_t( Bin& bin, Bin& in, Bin& out, REAL val )
  349. {
  350. /* tail at left, head on line */
  351. Arc_ptr j;
  352. while( j = bin.removearc() ) {
  353. assert( arc_classify( j, 1, val ) == 0x02 );
  354. j->clearitail();
  355. REAL diff = j->next->head()[1] - val;
  356. if( diff > 0.0 ) {
  357. in.addarc( j );
  358. } else if( diff < 0.0 ) {
  359. if( ccwTurn_tl( j, j->next ) )
  360. out.addarc( j );
  361. else
  362. in.addarc( j );
  363. } else {
  364. if (j->next->tail()[0] > j->next->head()[0] )
  365. out.addarc( j );
  366. else
  367. in.addarc( j );
  368. }
  369. }
  370. }
  371. void
  372. Subdivider::classify_headonleft_s( Bin& bin, Bin& in, Bin& out, REAL val )
  373. {
  374. /* tail on line, head at left */
  375. Arc_ptr j;
  376. while( j = bin.removearc() ) {
  377. assert( arc_classify( j, 0, val ) == 0x20 );
  378. j->setitail();
  379. REAL diff = j->prev->tail()[0] - val;
  380. if( diff > 0.0 ) {
  381. out.addarc( j );
  382. } else if( diff < 0.0 ) {
  383. if( ccwTurn_sl( j->prev, j ) )
  384. out.addarc( j );
  385. else
  386. in.addarc( j );
  387. } else {
  388. if( j->prev->tail()[1] > j->prev->head()[1] )
  389. in.addarc( j );
  390. else
  391. out.addarc( j );
  392. }
  393. }
  394. }
  395. void
  396. Subdivider::classify_headonleft_t( Bin& bin, Bin& in, Bin& out, REAL val )
  397. {
  398. /* tail on line, head at left */
  399. Arc_ptr j;
  400. while( j = bin.removearc() ) {
  401. assert( arc_classify( j, 1, val ) == 0x20 );
  402. j->setitail();
  403. REAL diff = j->prev->tail()[1] - val;
  404. if( diff > 0.0 ) {
  405. out.addarc( j );
  406. } else if( diff < 0.0 ) {
  407. if( ccwTurn_tl( j->prev, j ) )
  408. out.addarc( j );
  409. else
  410. in.addarc( j );
  411. } else {
  412. if( j->prev->tail()[0] > j->prev->head()[0] )
  413. out.addarc( j );
  414. else
  415. in.addarc( j );
  416. }
  417. }
  418. }
  419. void
  420. Subdivider::classify_tailonright_s( Bin& bin, Bin& in, Bin& out, REAL val )
  421. {
  422. /* tail at right, head on line */
  423. Arc_ptr j;
  424. while( j = bin.removearc() ) {
  425. assert( arc_classify( j, 0, val ) == 0x12);
  426. j->clearitail();
  427. REAL diff = j->next->head()[0] - val;
  428. if( diff > 0.0 ) {
  429. if( ccwTurn_sr( j, j->next ) )
  430. out.addarc( j );
  431. else
  432. in.addarc( j );
  433. } else if( diff < 0.0 ) {
  434. in.addarc( j );
  435. } else {
  436. if( j->next->tail()[1] > j->next->head()[1] )
  437. out.addarc( j );
  438. else
  439. in.addarc( j );
  440. }
  441. }
  442. }
  443. void
  444. Subdivider::classify_tailonright_t( Bin& bin, Bin& in, Bin& out, REAL val )
  445. {
  446. /* tail at right, head on line */
  447. Arc_ptr j;
  448. while( j = bin.removearc() ) {
  449. assert( arc_classify( j, 1, val ) == 0x12);
  450. j->clearitail();
  451. REAL diff = j->next->head()[1] - val;
  452. if( diff > 0.0 ) {
  453. if( ccwTurn_tr( j, j->next ) )
  454. out.addarc( j );
  455. else
  456. in.addarc( j );
  457. } else if( diff < 0.0 ) {
  458. in.addarc( j );
  459. } else {
  460. if( j->next->tail()[0] > j->next->head()[0] )
  461. in.addarc( j );
  462. else
  463. out.addarc( j );
  464. }
  465. }
  466. }
  467. void
  468. Subdivider::classify_headonright_s( Bin& bin, Bin& in, Bin& out, REAL val )
  469. {
  470. /* tail on line, head at right */
  471. Arc_ptr j;
  472. while( j = bin.removearc() ) {
  473. assert( arc_classify( j, 0, val ) == 0x21 );
  474. j->setitail();
  475. REAL diff = j->prev->tail()[0] - val;
  476. if( diff > 0.0 ) {
  477. if( ccwTurn_sr( j->prev, j ) )
  478. out.addarc( j );
  479. else
  480. in.addarc( j );
  481. } else if( diff < 0.0 ) {
  482. out.addarc( j );
  483. } else {
  484. if( j->prev->tail()[1] > j->prev->head()[1] )
  485. out.addarc( j );
  486. else
  487. in.addarc( j );
  488. }
  489. }
  490. }
  491. void
  492. Subdivider::classify_headonright_t( Bin& bin, Bin& in, Bin& out, REAL val )
  493. {
  494. /* tail on line, head at right */
  495. Arc_ptr j;
  496. while( j = bin.removearc() ) {
  497. assert( arc_classify( j, 1, val ) == 0x21 );
  498. j->setitail();
  499. REAL diff = j->prev->tail()[1] - val;
  500. if( diff > 0.0 ) {
  501. if( ccwTurn_tr( j->prev, j ) )
  502. out.addarc( j );
  503. else
  504. in.addarc( j );
  505. } else if( diff < 0.0 ) {
  506. out.addarc( j );
  507. } else {
  508. if( j->prev->tail()[0] > j->prev->head()[0] )
  509. in.addarc( j );
  510. else
  511. out.addarc( j );
  512. }
  513. }
  514. }