home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / POLYEDIT.LZH / MODEL / SELECT.C < prev    next >
C/C++ Source or Header  |  1996-03-18  |  11KB  |  605 lines

  1. /*
  2.  *        ポリゴンの編集処理
  3.  *
  4.  *        Copyright T.Kobayashi    1994.7.17
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <assert.h>
  10. #include "data.h"
  11. #include "poly.h"
  12. #include "view.h"
  13.  
  14. #define    swap( a, b )    { int    _w ; _w = a ; a = b ; b = _w ; }
  15.  
  16. int        Selects ;
  17.  
  18. static    void    SelectPoly( Polygon*, int, int, int );
  19.  
  20. /*    ポリゴンのセレクト(すべて)    */
  21. void    PolySelectAll( flag, sw )
  22. int        flag ;        /*    TRUE | FALSE    */
  23. int        sw ;            /*    AND | OR    */
  24. {
  25.     Polygon    *poly ;
  26.  
  27.     PolyPtr = NULL ;
  28.     Selects = 0 ;
  29.     poly = PolyTop();
  30.     while( poly != NULL )
  31.     {
  32.         SelectPoly( poly, TRUE, flag, sw );
  33.         poly = BufferNext( poly );
  34.     }
  35. }
  36.  
  37. /*    ポリゴンのセレクト(境界指定)    */
  38. void    PolySelectArea( flag, sw, pos1, pos2 )
  39. int        flag ;            /*    ON | OFF     */
  40. int        sw ;            /*    AND | OR    */
  41. Vertex    *pos1, *pos2 ;
  42. {
  43.     int        i ;
  44.     Polygon    *poly ;
  45.     Vertex    *ver ;
  46.     int        mode ;
  47.  
  48.     mode = sw & SELECT_SUB ;
  49.     sw &= SELECT_LOG ;
  50.     PolyPtr = NULL ;
  51.  
  52. #if    0
  53.     printf( "PolySelectArea ( %d, %d, %d )-( %d, %d, %d )\n",
  54.         pos1->x, pos1->y, pos1->z, pos2->x, pos2->y, pos2->z );
  55. #endif
  56.  
  57.     if ( pos1->x > pos2->x )
  58.         swap( pos1->x, pos2->x );
  59.     if ( pos1->y > pos2->y )
  60.         swap( pos1->y, pos2->y );
  61.     if ( pos1->z > pos2->z )
  62.         swap( pos1->z, pos2->z );
  63.  
  64. #if    0
  65.     if ( pos1->x == pos2->x )
  66.     {
  67.         pos1->x = -32767 ;
  68.         pos2->x = 32767 ;
  69.     }
  70.     if ( pos1->y == pos2->y )
  71.     {
  72.         pos1->y = -32767 ;
  73.         pos2->y = 32767 ;
  74.     }
  75.     if ( pos1->z == pos2->z )
  76.     {
  77.         pos1->z = -32767 ;
  78.         pos2->z = 32767 ;
  79.     }
  80. #endif
  81.  
  82.     Selects = 0 ;
  83.     poly = PolyTop();
  84.     while( poly != NULL )
  85.     {
  86.         ver = poly->ver ;
  87.         for( i = poly->vers ; i > 0 ; i-- )
  88.         {
  89.             if ( pos1->x <= ver->x && ver->x <= pos2->x &&
  90.                  pos1->y <= ver->y && ver->y <= pos2->y &&
  91.                  pos1->z <= ver->z && ver->z <= pos2->z )
  92.             {
  93.                 if ( mode == SELECT_SUB )
  94.                     break ;
  95.             }
  96.             else
  97.             {
  98.                 if ( mode == SELECT_ALL )
  99.                     break ;
  100.             }
  101.             ver++ ;
  102.         }
  103.         SelectPoly( poly, ( i == 0 ) ^ ( mode == SELECT_SUB ), flag, sw );
  104.         poly = BufferNext( poly );
  105.     }
  106. }
  107.  
  108. /*    ポリゴンのセレクト(透視図で指定)    */
  109. void    PolySelectPers( flag, sw, x1, y1, x2, y2 )
  110. int        flag ;            /*    ON | OFF     */
  111. int        sw ;            /*    AND | OR    */
  112. int        x1, y1, x2, y2 ;
  113. {
  114.     int        i ;
  115.     Polygon    *poly ;
  116.     Vertex    *ver ;
  117.     int        scr[2] ;
  118.     int        mode ;
  119.  
  120.     mode = sw & SELECT_SUB ;
  121.     sw &= SELECT_SUB - 1 ;
  122.     PolyPtr = NULL ;
  123.  
  124.     x1 =   ((x1 * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.x + WinPers.h / 2 ;
  125.     y1 = - ((y1 * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.y + WinPers.v / 2 ;
  126.     x2 =   ((x2 * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.x + WinPers.h / 2 ;
  127.     y2 = - ((y2 * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.y + WinPers.v / 2 ;
  128.     if ( x1 > x2 )
  129.         swap( x1, x2 );
  130.     if ( y1 > y2 )
  131.         swap( y1, y2 );
  132.  
  133.     Selects = 0 ;
  134.     poly = PolyTop();
  135.     while( poly != NULL )
  136.     {
  137.         ver = poly->ver ;
  138.         for( i = poly->vers ; i > 0 ; i-- )
  139.         {
  140.             if ( ToScreenPers( scr, ver ) && x1-1 <= scr[0] && scr[0] <= x2+1 && y1-1 <= scr[1] && scr[1] <= y2+1 )
  141.             {
  142.                 if ( mode == SELECT_SUB )
  143.                         break ;
  144.             }
  145.             else
  146.             {
  147.                 if ( mode == SELECT_ALL )
  148.                     break ;
  149.             }
  150.             ver++ ;
  151.         }
  152.         SelectPoly( poly, ( i == 0 ) ^ ( mode == SELECT_SUB ), flag, sw );
  153.         poly = PolyNext( poly );
  154.     }
  155. }
  156.  
  157. /*    アトリビュートをセレクト    */
  158. void    PolySelectAttr( atrno, flag, sw )
  159. int        atrno, flag, sw ;
  160. {
  161.     Polygon    *poly ;
  162.     PolyPtr = NULL ;
  163.  
  164.     Selects = 0 ;
  165.     poly = PolyTop();
  166.     while( poly != NULL )
  167.     {
  168.         SelectPoly( poly, poly->atr == atrno, flag, sw );
  169.         poly = BufferNext( poly );
  170.     }
  171. }
  172.  
  173. /*    オブジェクトをセレクト    */
  174. void    PolySelectObj( objno, flag, sw )
  175. int        objno, flag, sw ;
  176. {
  177.     Polygon    *poly ;
  178.     PolyPtr = NULL ;
  179.  
  180.     Selects = 0 ;
  181.     poly = PolyTop();
  182.     while( poly != NULL )
  183.     {
  184.         SelectPoly( poly, poly->obj == objno, flag, sw );
  185.         poly = BufferNext( poly );
  186.     }
  187. }
  188.  
  189. /*    オブジェクトをセレクト    */
  190. void    PolySelectPolyType( type, flag, sw )
  191. int        type, flag, sw ;
  192. {
  193.     Polygon    *poly ;
  194.     PolyPtr = NULL ;
  195.  
  196.     Selects = 0 ;
  197.     poly = PolyTop();
  198.     while( poly != NULL )
  199.     {
  200.         SelectPoly( poly, poly->type == type, flag, sw );
  201.         poly = BufferNext( poly );
  202.     }
  203. }
  204.  
  205. /*    セレクトしているポリゴンのボックスを得る    */
  206. int        SelectBox( min, max )
  207. Vertex    *min ;
  208. Vertex    *max ;
  209. {
  210.     int        i, flag ;
  211.     Polygon    *poly ;
  212.     Vertex    *ver ;
  213.  
  214.     flag = FALSE ;
  215.     poly = PolyTop();
  216.     min->x = min->y = min->z = 32767 ;
  217.     max->x = max->y = max->z = -32767 ;
  218.     while( poly != NULL )
  219.     {
  220.         if ( poly->select == ON )
  221.         {
  222.             ver = poly->ver ;
  223.             for( i = poly->vers ; i > 0 ; i-- )
  224.             {
  225.                 if ( min->x > ver->x )
  226.                     min->x = ver->x ;
  227.                 if ( min->y > ver->y )
  228.                     min->y = ver->y ;
  229.                 if ( min->z > ver->z )
  230.                     min->z = ver->z ;
  231.                 if ( max->x < ver->x )
  232.                     max->x = ver->x ;
  233.                 if ( max->y < ver->y )
  234.                     max->y = ver->y ;
  235.                 if ( max->z < ver->z )
  236.                     max->z = ver->z ;
  237.                 ver ++ ;
  238.             }
  239.             flag = TRUE ;
  240.         }
  241.         poly = PolyNext( poly );
  242.     }
  243.     return flag ;
  244. }
  245.  
  246. static    void    SelectPoly( poly, sel, flag, sw )
  247. Polygon    *poly ;
  248. int        sel ;
  249. int        flag ;    /*    ON | OFF    */
  250. int        sw ;    /*    UPDATE | AND | OR | XOR    */
  251. {
  252.     if ( poly->mode & MODE_INVISIBLE )
  253.         return ;
  254.  
  255.     if ( ! sel )
  256.         flag = ! flag ;
  257.  
  258.     switch( sw & SELECT_LOG )
  259.     {
  260.         case SELECT_UPDATE:
  261.             poly->select = flag ;
  262.             break ;
  263.         case SELECT_AND:
  264.             poly->select &= flag ;
  265.             break ;
  266.         case SELECT_OR:
  267.             poly->select |= flag ;
  268.             break ;
  269.         case SELECT_XOR:
  270.             poly->select ^= flag ;
  271.             break ;
  272.         default:
  273.             assert( FALSE );
  274.     }
  275.  
  276.     if ( poly->select )
  277.         Selects ++ ;
  278. }
  279.  
  280. /*    セレクト状態を保存する    */
  281. void    SelectSave( sel )
  282. SelectClass    *sel ;
  283. {
  284.     Polygon    *poly ;
  285.     int        bit, polys ;
  286.     int        *buf ;
  287.  
  288.     polys = 0 ;
  289.     buf = sel->selbuf ;
  290.     bit = 1 ;
  291.     *buf = 0 ;
  292.     poly = PolyTop();
  293.     while( poly != NULL )
  294.     {
  295.         polys ++ ;
  296.         if ( poly->select )
  297.             *buf |= bit ;
  298.         if ( bit == 0x80000000 )
  299.         {
  300.             bit = 1 ;
  301.             buf++ ;
  302.             *buf = 0 ;
  303.         }
  304.         else
  305.             bit <<= 1 ;
  306.         poly = BufferNext( poly );
  307.     }
  308.     sel->polys = polys ;
  309. }
  310.  
  311. /*    カレントポリゴンのセレクトを作る    */
  312. void    SelectCurrent( sel )
  313. SelectClass    *sel ;
  314. {
  315.     Polygon    *poly ;
  316.     int        bit, polys ;
  317.     int        *buf ;
  318.  
  319.     polys = 0 ;
  320.     buf = sel->selbuf ;
  321.     bit = 1 ;
  322.     *buf = 0 ;
  323.     poly = PolyTop();
  324.     while( poly != NULL )
  325.     {
  326.         polys ++ ;
  327.         if ( poly == PolyPtr )
  328.             *buf |= bit ;
  329.         if ( bit == 0x80000000 )
  330.         {
  331.             bit = 1 ;
  332.             buf++ ;
  333.             *buf = 0 ;
  334.         }
  335.         else
  336.             bit <<= 1 ;
  337.         poly = BufferNext( poly );
  338.     }
  339.     sel->polys = polys ;
  340. }
  341.  
  342. /*    セレクト状態の保存を復帰する    */
  343. void    SelectLoad( sel )
  344. SelectClass    *sel ;
  345. {
  346.     Polygon    *poly ;
  347.     int        bit, polys ;
  348.     int        *buf ;
  349.  
  350.     PolyPtr = NULL ;
  351.  
  352.     buf = sel->selbuf ;
  353.  
  354.     bit = 1 ;
  355.     Selects = 0 ;
  356.     polys = sel->polys ;
  357.     poly = PolyTop();
  358.     while( poly != NULL )
  359.     {
  360.         if ( ( *buf & bit ) && ( polys > 0 ) )
  361.         {
  362.             poly->select = ON ;
  363.             Selects ++ ;
  364.         }
  365.         else
  366.             poly->select = OFF ;
  367.         if ( bit == 0x80000000 )
  368.         {
  369.             bit = 1 ;
  370.             buf++ ;
  371.         }
  372.         else
  373.             bit <<= 1 ;
  374.         poly = BufferNext( poly );
  375.         polys -- ;
  376.     }
  377. }
  378.  
  379. /*    セレクト状態の中からn番目のポリゴンだけをセレクトする    */
  380. int        SelectNumber( sel, n )
  381. SelectClass    *sel ;
  382. int            n ;
  383. {
  384.     Polygon    *poly ;
  385.     int        bit ;
  386.     int        *buf ;
  387.  
  388.     PolyPtr = NULL ;
  389.     if ( n < 0 )
  390.         return FALSE ;
  391.  
  392.     buf = sel->selbuf ;
  393.     bit = 1 ;
  394.     Selects = 0 ;
  395.     poly = PolyTop();
  396.     while( poly != NULL )
  397.     {
  398.         if ( *buf & bit )
  399.         {
  400.             if ( n == 0 )
  401.             {
  402.                 poly->select = ON ;
  403.                 Selects ++ ;
  404.             }
  405.             else
  406.                 poly->select = OFF ;
  407.             n -- ;
  408.         }
  409.         else
  410.             poly->select = OFF ;
  411.         if ( bit == 0x80000000 )
  412.         {
  413.             bit = 1 ;
  414.             buf++ ;
  415.         }
  416.         else
  417.             bit <<= 1 ;
  418.         poly = BufferNext( poly );
  419.     }
  420.     return n < 0 ;
  421. }
  422.  
  423. /*    セレクト状態のn番目のポリゴンを返す    */
  424. Polygon *GetSelectPolyNumber( sel, n )
  425. SelectClass    *sel ;
  426. int            n ;
  427. {
  428.     Polygon    *poly ;
  429.     int        bit ;
  430.     int        *buf ;
  431.  
  432.     if ( n < 0 )
  433.         return FALSE ;
  434.  
  435.     buf = sel->selbuf ;
  436.     bit = 1 ;
  437.  
  438.     poly = PolyTop();
  439.     while( poly != NULL )
  440.     {
  441.         if ( *buf & bit )
  442.         {
  443.             if ( n == 0 )
  444.             {
  445.                 return poly;
  446.             }
  447.             n -- ;
  448.         }
  449.         if ( bit == 0x80000000 )
  450.         {
  451.             bit = 1 ;
  452.             buf++ ;
  453.         }
  454.         else
  455.             bit <<= 1 ;
  456.         poly = BufferNext( poly );
  457.     }
  458.     return NULL;
  459. }
  460.  
  461.  
  462. /*    セレクトのポリゴン数    */
  463. int    SelectPolygons( sel )
  464. SelectClass    *sel ;
  465. {
  466.     Polygon    *poly ;
  467.     int        bit, polys ;
  468.     int        *buf ;
  469.     int s;
  470.  
  471.     buf = sel->selbuf ;
  472.     s = 0;
  473.  
  474.     bit = 1 ;
  475.     poly = PolyTop();
  476.     for (polys = sel->polys; polys > 0; polys--) {
  477.         if (*buf & bit)
  478.             s ++ ;
  479.         if ( bit == 0x80000000 )
  480.         {
  481.             bit = 1 ;
  482.             buf++ ;
  483.         }
  484.         else
  485.             bit <<= 1 ;
  486.     }
  487.     return s;
  488. }
  489.  
  490. /*    セレクトされているポリゴン削除する    */
  491. void    PolySelectDelete( sel )
  492. SelectClass    *sel ;
  493. {
  494.  
  495.     Polygon    *poly, *next ;
  496.     int        bit, polys ;
  497.     int        *buf ;
  498.  
  499.     buf = sel->selbuf ;
  500.     bit = 1 ;
  501.     poly = PolyTop();
  502.     polys = sel->polys;
  503.     Selects = 0 ;
  504.  
  505.     while( poly != NULL  && polys > 0)
  506.     {
  507.         next = PolyNext( poly );
  508.         if ( *buf & bit ) {
  509.             ObjData[poly->obj].edit = TRUE ;
  510.             BufferDelete( poly );
  511.         } else if (poly->select == ON) {
  512.             Selects ++ ;
  513.         }
  514.  
  515.         if ( bit == 0x80000000 )
  516.         {
  517.             bit = 1 ;
  518.             buf++ ;
  519.         }
  520.         else
  521.             bit <<= 1 ;
  522.  
  523.         poly = next;
  524.         polys--;
  525.     }
  526.     while (poly != NULL) {
  527.         if (poly->select == ON) {
  528.             Selects ++ ;
  529.         }
  530.         poly = PolyNext(poly);
  531.     }
  532.     BufferDeleteCorrect();
  533. }
  534.  
  535. /*    セレクトされているポリゴンに隣接するポリゴンを選択する    */
  536. void    SelectAdjoint( seldst, selsrc )
  537. SelectClass    *seldst, *selsrc ;
  538. {
  539.     int i, j;
  540.     Polygon    *dstpoly, *srcpoly ;
  541.     int        dstbit, srcbit, polys ;
  542.     int        *dstbuf, *srcbuf;
  543.     int flag;
  544.     Vertex    *srcver, *dstver ;
  545.  
  546.     polys = 0 ;
  547.     dstbuf = seldst->selbuf ;
  548.     dstbit = 1 ;
  549.     *dstbuf = 0 ;
  550.     dstpoly = PolyTop();
  551.     while( dstpoly != NULL )
  552.     {
  553.         flag = FALSE;
  554.         srcbuf = selsrc->selbuf ;
  555.         srcbit = 1 ;
  556.         srcpoly = PolyTop();
  557.         if ((dstpoly->mode & MODE_INVISIBLE) == 0) {
  558.             while( srcpoly != NULL )
  559.             {
  560.                 if ((srcpoly->mode & MODE_INVISIBLE) == 0 && (*srcbuf & srcbit) != 0) {
  561.                     srcver = srcpoly->ver ;
  562.                     for (i = srcpoly->vers ; i > 0 ; i--) {
  563.                         dstver = dstpoly->ver;
  564.                         for (j = dstpoly->vers; j > 0; j--) {
  565.                             if (srcver->x == dstver->x
  566.                              && srcver->y == dstver->y
  567.                              && srcver->z == dstver->z) {
  568.                                 flag = TRUE;
  569.                                 break;
  570.                             }
  571.                             dstver++;
  572.                         }
  573.                         if (flag) break;
  574.                         srcver++;
  575.                     }
  576.                     if (flag) break;
  577.                 }
  578.                 if ( srcbit == 0x80000000 )
  579.                 {
  580.                     srcbit = 1 ;
  581.                     srcbuf++ ;
  582.                 }
  583.                 else
  584.                     srcbit <<= 1 ;
  585.                 srcpoly = BufferNext( srcpoly );
  586.             }
  587.         }
  588.         polys ++ ;
  589.         if ( flag )
  590.             *dstbuf |= dstbit ;
  591.         if ( dstbit == 0x80000000 )
  592.         {
  593.             dstbit = 1 ;
  594.             dstbuf++ ;
  595.             *dstbuf = 0 ;
  596.         }
  597.         else
  598.             dstbit <<= 1 ;
  599.         dstpoly = BufferNext( dstpoly );
  600.     }
  601.     seldst->polys = polys ;
  602. }
  603.  
  604.  
  605.