home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / POLYEDIT.LZH / MODEL / SELLIB.C < prev    next >
C/C++ Source or Header  |  1996-02-29  |  14KB  |  566 lines

  1. /*
  2.  *    ポリゴン選択
  3.  *
  4.  *        Copyright T.Kobayashi    1994.7.9
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <assert.h>
  11.  
  12. #include "matrix.h"
  13. #include "vector.h"
  14. #include "matclass.h"
  15. #include "strclass.h"
  16. #include "ml.h"
  17.  
  18. #include "poly.h"
  19. #include "menu.h"
  20. #include "graph.h"
  21. #include "input.h"
  22.  
  23. static    int        FuncSelectPolygons( int, int, DataStruct* );
  24. static    int        FuncSelectAll( int, int, DataStruct* );
  25. static    int        FuncSelectArea( int, int, DataStruct* );
  26. static    int        FuncSelectPers( int, int, DataStruct* );
  27. static    int        FuncSelectAttr( int, int, DataStruct* );
  28. static    int        FuncSelectObj( int, int, DataStruct* );
  29. static    int        FuncSelectPolyType( int, int, DataStruct* );
  30. static    int        FuncSelectBox( int, int, DataStruct* );
  31. static    int        FuncSelectSave( int, int, DataStruct* );
  32. static    int        FuncSelectLoad( int, int, DataStruct* );
  33. static    int        FuncSelectAdjoint( int, int, DataStruct* );
  34. static    int        FuncSelectNumber( int, int, DataStruct* );
  35. static    int        FuncSelectPolyDelete( int, int, DataStruct* );
  36. static    int        FuncSelectEqual( int, int, DataStruct* );
  37. static    int        FuncSelectLogical( int, int, DataStruct* );
  38. static    int        FuncToString( int, int, DataStruct* );
  39. static    int        FuncPolyLoad( int, int, DataStruct* );
  40. static    int        FuncSelectCurrent( int, int, DataStruct* );
  41.  
  42. int        SelectClassID ;
  43.  
  44. void    SelectLibInit()
  45. {
  46.     SelectClassID = NewClass( "Select", 0 );
  47.  
  48.     NewFunction( 0, "SelectPolygons", FuncSelectPolygons );
  49.     NewFunction( 0, "SelectAll", FuncSelectAll );
  50.     NewFunction( 0, "SelectArea", FuncSelectArea );
  51.     NewFunction( 0, "SelectPers", FuncSelectPers );
  52.     NewFunction( 0, "SelectAttr", FuncSelectAttr );
  53.     NewFunction( 0, "SelectObj", FuncSelectObj );
  54.     NewFunction( 0, "SelectPolyType", FuncSelectPolyType );
  55.     NewFunction( 0, "SelectBox", FuncSelectBox );
  56.     NewFunction( 0, "Select", FuncSelectSave );
  57.     NewFunction( 0, "SelectCurrent", FuncSelectCurrent );
  58.     NewFunction( SelectClassID, "SelectAdjoint", FuncSelectAdjoint );
  59.     NewFunction( SelectClassID, "tostring", FuncToString );
  60.     NewFunction( SelectClassID, "SelectPolygons", FuncSelectPolygons );
  61.     NewFunction( SelectClassID, "Select", FuncSelectLoad );
  62.     NewFunction( SelectClassID, "SelectNumber", FuncSelectNumber );
  63.     NewFunction( SelectClassID, "PolyDelete", FuncSelectPolyDelete );
  64.     NewFunction( SelectClassID, "PolyLoad", FuncPolyLoad );
  65.  
  66.     NewOperator( SelectClassID, OPE_NOT, FuncSelectLogical );
  67.     NewOperator( SelectClassID, OPE_AND, FuncSelectLogical );
  68.     NewOperator( SelectClassID, OPE_OR, FuncSelectLogical );
  69.     NewOperator( SelectClassID, OPE_XOR, FuncSelectLogical );
  70.     NewOperator( SelectClassID, OPE_EQ, FuncSelectEqual );
  71.     NewOperator( SelectClassID, OPE_NOTEQ, FuncSelectEqual );
  72. }
  73.  
  74. /*    セレクトしているポリゴンの数を得る    */
  75. static    int        FuncSelectPolygons( ident, args, buf )
  76. int        ident ;
  77. int        args ;
  78. DataStruct    *buf ;
  79. {
  80.     if (args == 0) {
  81.         StackPushInt( Selects );
  82.     } else {
  83.         ArgCheck( "SelectPolygons", args, buf, TYPE_OBJECT, TYPE_NOASN );
  84.         StackPushInt( SelectPolygons((SelectClass*)(buf->od.ptr)));
  85.     }
  86.     return RETURN_RETURN ;
  87. }
  88.  
  89. /*    ポリゴンのセレクト(すべて)    */
  90. static    int        FuncSelectAll( ident, args, buf )
  91. int        ident ;
  92. int        args ;
  93. DataStruct    *buf ;
  94. {
  95.     if ( args == 1 )
  96.     {
  97.         ArgCheck( "SelectAll", args, buf, TYPE_INT|TYPE_BOOLEAN, TYPE_NOASN );
  98.         PolySelectAll( buf[0].id.i, SELECT_UPDATE );
  99.     }
  100.     else
  101.     {
  102.         ArgCheck( "SelectAll", args, buf, TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_NOASN );
  103.         PolySelectAll( buf[0].id.i, buf[1].id.i );
  104.     }
  105.     return RETURN_VOID ;
  106. }
  107.  
  108. /*    ポリゴンのセレクト(境界指定)    */
  109. static    int        FuncSelectArea( ident, args, buf )
  110. int        ident ;
  111. int        args ;
  112. DataStruct    *buf ;
  113. {
  114.     Vertex    *v1, *v2 ;
  115.     ArgCheck( "SelectArea", args, buf,
  116.             TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_OBJECT, TYPE_OBJECT, TYPE_NOASN );
  117.  
  118.     if ( ObjectCheck( &buf[2], VertexClassID ) == FALSE ||
  119.         ObjectCheck( &buf[3], VertexClassID ) == FALSE )
  120.     {
  121.         ExecError( "引数の型が不正です。(SelectArea)" );
  122.     }
  123.     v1 = &((VertexClass*)buf[2].od.ptr)->ver ;
  124.     v2 = &((VertexClass*)buf[3].od.ptr)->ver ;
  125.  
  126.     PolySelectArea( buf[0].id.i, buf[1].id.i, v1, v2 );
  127.     return RETURN_VOID ;
  128. }
  129.  
  130. /*    ポリゴンのセレクト(透視図で指定)    */
  131. static    int        FuncSelectPers( ident, args, buf )
  132. int        ident ;
  133. int        args ;
  134. DataStruct    *buf ;
  135. {
  136.     ArgCheck( "SelectPers", args, buf,
  137.             TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_NOASN );
  138.  
  139.     PolySelectPers( buf[0].id.i, buf[1].id.i,
  140.             buf[2].id.i, buf[3].id.i, buf[4].id.i, buf[5].id.i );
  141.     return RETURN_VOID ;
  142. }
  143.  
  144. /*    アトリビュートをセレクト    */
  145. static    int        FuncSelectAttr( ident, args, buf )
  146. int        ident ;
  147. int        args ;
  148. DataStruct    *buf ;
  149. {
  150.     ArgCheck( "SelectAttr", args, buf, TYPE_INT, TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_NOASN );
  151.  
  152.     PolySelectAttr( buf[0].id.i, buf[1].id.i, buf[2].id.i );
  153.     return RETURN_VOID ;
  154. }
  155.  
  156. /*    オブジェクトをセレクト    */
  157. static    int        FuncSelectObj( ident, args, buf )
  158. int        ident ;
  159. int        args ;
  160. DataStruct    *buf ;
  161. {
  162.     ArgCheck( "SelectObj", args, buf, TYPE_INT, TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_NOASN );
  163.  
  164.     PolySelectObj( buf[0].id.i, buf[1].id.i, buf[2].id.i );
  165.     return RETURN_VOID ;
  166. }
  167.  
  168. /*    オブジェクトをセレクト    */
  169. static    int        FuncSelectPolyType( ident, args, buf )
  170. int        ident ;
  171. int        args ;
  172. DataStruct    *buf ;
  173. {
  174.     ArgCheck( "SelectPolyType", args, buf, TYPE_INT, TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_NOASN );
  175.  
  176.     PolySelectPolyType( buf[0].id.i, buf[1].id.i, buf[2].id.i );
  177.     return RETURN_VOID ;
  178. }
  179.  
  180. /*    セレクトしているポリゴンのボックスを得る    */
  181. static    int        FuncSelectBox( ident, args, buf )
  182. int        ident ;
  183. int        args ;
  184. DataStruct    *buf ;
  185. {
  186.     int        i ;
  187.     VertexClass    *min, *max ;
  188.  
  189.     ArgCheck( "SelectBox", args, buf, TYPE_ARRAY, TYPE_NOASN );
  190.  
  191.     if ( buf[0].ad.size < 2 )
  192.         ExecError( "引数配列のサイズが不正です。(SelectBox)" );
  193.     buf = buf[0].ad.ary ;
  194.     for( i = 0 ; i < 2 ; i++ )
  195.     {
  196.         if ( buf[i].type == TYPE_OBJECT )
  197.             ObjectFree( buf[i].od.ptr );
  198.         buf[i].type = TYPE_OBJECT ;
  199.     }
  200.  
  201.     min = (VertexClass*)ObjectAlloc( sizeof( VertexClass ), VertexClassID );
  202.     max = (VertexClass*)ObjectAlloc( sizeof( VertexClass ), VertexClassID );
  203.     min->dtype = max->dtype = POLY_SIMPLE ;
  204.     buf[0].od.ptr = (Object*)min ;
  205.     buf[1].od.ptr = (Object*)max ;
  206.  
  207.     StackPushBoolean( SelectBox( &min->ver, &max->ver ) );
  208.     return RETURN_RETURN ;
  209. }
  210.  
  211. /*    セレクト状態を保存する    */
  212. static    int        FuncSelectSave( ident, args, buf )
  213. int        ident ;
  214. int        args ;
  215. DataStruct    *buf ;
  216. {
  217.     int        size ;
  218.     SelectClass    *sel ;
  219.  
  220.     size = ( Polygons() / 32 + 1 ) * sizeof( int ) + sizeof( SelectClass ) ;
  221.     sel = (SelectClass*)ObjectAlloc( size, SelectClassID );
  222.     SelectSave( sel );
  223.  
  224.     buf = StackAlloc( 1 );
  225.     buf->type = TYPE_OBJECT ;
  226.     buf->od.ptr = (Object*)sel ;
  227.  
  228.     return RETURN_RETURN ;
  229. }
  230.  
  231. /*    カレントポリゴンのセレクト状態をつくる    */
  232. static    int        FuncSelectCurrent( ident, args, buf )
  233. int        ident ;
  234. int        args ;
  235. DataStruct    *buf ;
  236. {
  237.     int        size ;
  238.     SelectClass    *sel ;
  239.  
  240.     size = ( Polygons() / 32 + 1 ) * sizeof( int ) + sizeof( SelectClass ) ;
  241.     sel = (SelectClass*)ObjectAlloc( size, SelectClassID );
  242.     SelectCurrent( sel );
  243.  
  244.     buf = StackAlloc( 1 );
  245.     buf->type = TYPE_OBJECT ;
  246.     buf->od.ptr = (Object*)sel ;
  247.  
  248.     return RETURN_RETURN ;
  249. }
  250.  
  251. /*    セレクト状態の保存を復帰する    */
  252. static    int        FuncSelectLoad( ident, args, buf )
  253. int        ident ;
  254. int        args ;
  255. DataStruct    *buf ;
  256. {
  257.     ArgCheck( "SelectLoad", args, buf, TYPE_OBJECT, TYPE_NOASN );
  258.     SelectLoad( (SelectClass*)buf[0].od.ptr );
  259.  
  260.     StackPush( &buf[0] );
  261.  
  262.     return RETURN_RETURN ;
  263. }
  264.  
  265. static    int        FuncSelectAdjoint( ident, args, buf )
  266. int        ident ;
  267. int        args ;
  268. DataStruct    *buf ;
  269. {
  270.     int size;
  271.     SelectClass    *sel ;
  272.  
  273.     ArgCheck( "SelectAdjoint", args, buf, TYPE_OBJECT, TYPE_NOASN );
  274.  
  275.     size = ( Polygons() / 32 + 1 ) * sizeof( int ) + sizeof( SelectClass ) ;
  276.     sel = (SelectClass*)ObjectAlloc( size, SelectClassID );
  277.  
  278.     SelectAdjoint( sel, (SelectClass*)buf[0].od.ptr );
  279.  
  280.     buf = StackAlloc( 1 );
  281.     buf->type = TYPE_OBJECT ;
  282.     buf->od.ptr = (Object*)sel ;
  283.  
  284.     return RETURN_RETURN ;
  285. }
  286.  
  287.  
  288. /*    セレクト状態の中からn番目のポリゴンだけをセレクトする    */
  289. static    int        FuncSelectNumber( ident, args, buf )
  290. int        ident ;
  291. int        args ;
  292. DataStruct    *buf ;
  293. {
  294.     ArgCheck( "SelectNumber", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
  295.     StackPushInt( SelectNumber( (SelectClass*)buf[0].od.ptr, buf[1].id.i ) );
  296.  
  297.     return RETURN_RETURN ;
  298. }
  299.  
  300. static    int        FuncPolyLoad( ident, args, buf )
  301. int        ident ;
  302. int        args ;
  303. DataStruct    *buf ;
  304. {
  305.     SelectClass *sel;
  306.     int pos;
  307.     ArgCheck( "PolyLoad", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
  308.     sel = (SelectClass*)buf[0].od.ptr;
  309.     pos = buf[1].id.i;
  310.  
  311.     StackPushInt((int)PolyLoadPtr(GetSelectPolyNumber(sel, pos)));
  312.     return RETURN_RETURN ;
  313. }
  314.  
  315. /*    セレクト状態の保存を復帰する    */
  316. static    int        FuncSelectPolyDelete( ident, args, buf )
  317. int        ident ;
  318. int        args ;
  319. DataStruct    *buf ;
  320. {
  321.     ArgCheck( "PolyDelete", args, buf, TYPE_OBJECT, TYPE_NOASN );
  322.     PolySelectDelete( (SelectClass*)buf[0].od.ptr );
  323.  
  324.     return RETURN_VOID ;
  325. }
  326.  
  327. #if 0
  328. /*    セレクト状態の論理演算    */
  329. static    int        FuncSelectLogical( ident, args, buf )
  330. int        ident ;
  331. int        args ;
  332. DataStruct    *buf ;
  333. {
  334.     int        *p1, *p2, *pr ;
  335.     int        i, size ;
  336.     SelectClass    *sel1, *sel2, *ret ;
  337.  
  338.     sel1 = (SelectClass*)buf[0].od.ptr ;
  339.     p1 = sel1->selbuf ;
  340. /*
  341.     size = ( sel1->size - sizeof( SelectClass ) ) / sizeof( int ) ;
  342. */
  343.     size = (sel1->polys+31)/32;
  344.  
  345.     if ( args == 2 )
  346.     {
  347.         if ( ObjectCheck( &buf[1], SelectClassID ) == FALSE )
  348.             ExecError( "論理演算の型が不正です(Select)" );
  349.         sel2 = (SelectClass*)buf[1].od.ptr ;
  350.         p2 = sel2->selbuf ;
  351.     }
  352.  
  353.     ret = (SelectClass*)ObjectAlloc(
  354.             sizeof( SelectClass ) + size*sizeof( int ), SelectClassID );
  355.     pr = ret->selbuf ;
  356.     ret->polys = sel1->polys;
  357.  
  358.     for( i = 0 ; i < size ; i++ )
  359.     {
  360.         switch( ident )
  361.         {
  362.             case OPE_NOT:
  363.                 *pr++ = ~ *p1++ ;
  364.                 break ;
  365.             case OPE_AND:
  366.                 *pr++ = *p1++ & *p2++ ;
  367.                 break ;
  368.             case OPE_OR:
  369.                 *pr++ = *p1++ | *p2++ ;
  370.                 break ;
  371.             case OPE_XOR:
  372.                 *pr++ = *p1++ ^ *p2++ ;
  373.                 break ;
  374.             default:
  375.                 assert( FALSE );
  376.         }
  377.     }
  378.  
  379.     buf = StackAlloc( 1 );
  380.     buf->type = TYPE_OBJECT ;
  381.     buf->od.ptr = (Object*)ret ;
  382.  
  383.     return RETURN_RETURN ;
  384. }
  385. #else
  386. /*    セレクト状態の論理演算    */
  387. static    int        FuncSelectLogical( ident, args, buf )
  388. int        ident ;
  389. int        args ;
  390. DataStruct    *buf ;
  391. {
  392.     int        *p1, *p2, *pr ;
  393.     int        i, size, size1, size2 ;
  394.     SelectClass    *sel1, *sel2, *ret ;
  395.  
  396.     size = ( Polygons() + 31) / 32;
  397.  
  398.     sel1 = (SelectClass*)buf[0].od.ptr ;
  399.     p1 = sel1->selbuf ;
  400.     size1 = ( sel1->polys + 31) / 32;
  401.     if (size < size1) size1 = size;
  402.  
  403.     if ( args == 2 )
  404.     {
  405.         if ( ObjectCheck( &buf[1], SelectClassID ) == FALSE )
  406.             ExecError( "論理演算の型が不正です(Select)" );
  407.         sel2 = (SelectClass*)buf[1].od.ptr ;
  408.         p2 = sel2->selbuf ;
  409.         size2 = ( sel2->polys + 31) / 32;
  410.         if (size < size2) size2 = size;
  411.     }
  412.  
  413.     ret = (SelectClass*)ObjectAlloc(
  414.             sizeof( SelectClass ) + size*sizeof( int ), SelectClassID );
  415.     ret->polys = Polygons();
  416.  
  417.     pr = ret->selbuf ;
  418.     for (i = 0; i < size1; i++) {
  419.         *pr++ = *p1++;
  420.     }
  421.     for (; i < size; i++) {
  422.         *pr++ = 0;
  423.     }
  424.     pr = ret->selbuf ;
  425.     switch (ident) {
  426.     case OPE_NOT:
  427.         for (i = 0; i < size; i++, pr++) {
  428.             *pr = ~ *pr;
  429.         }
  430.         break;
  431.     case OPE_AND:
  432.         for (i = 0; i < size2; i++,pr++) {
  433.             *pr &= *p2++ ;
  434.         }
  435.         for (; i < size; i++, pr++) {
  436.             *pr = 0;
  437.         }
  438.         break;
  439.     case OPE_OR:
  440.         for (i = 0; i < size2; i++,pr++) {
  441.             *pr |= *p2++ ;
  442.         }
  443.         break ;
  444.     case OPE_XOR:
  445.         for (i = 0; i < size2; i++,pr++) {
  446.             *pr ^= *p2++ ;
  447.         }
  448.         break ;
  449.     default:
  450.         ExecError("演算子が不正です。(SelectClass)");
  451.     }
  452.  
  453.     buf = StackAlloc( 1 );
  454.     buf->type = TYPE_OBJECT ;
  455.     buf->od.ptr = (Object*)ret ;
  456.  
  457.     return RETURN_RETURN ;
  458. }
  459. #endif
  460.  
  461. /*    セレクト状態の論理演算    */
  462. static    int        FuncSelectEqual( ident, args, buf )
  463. int        ident ;
  464. int        args ;
  465. DataStruct    *buf ;
  466. {
  467.     int        *p1, *p2;
  468.     int        i, size, size1, size2 ;
  469.     SelectClass    *sel1, *sel2;
  470.     int flag;
  471.  
  472.     size = ( Polygons() + 31) / 32;
  473.  
  474.     if (args != 2 || ObjectCheck( &buf[1], SelectClassID ) == FALSE ) {
  475.         ExecError( "論理演算の型が不正です(Select)" );
  476.     }
  477.  
  478.     sel1 = (SelectClass*)buf[0].od.ptr ;
  479.     p1 = sel1->selbuf ;
  480.     size1 = ( sel1->polys + 31) / 32;
  481.     if (size < size1) size1 = size;
  482.  
  483.     sel2 = (SelectClass*)buf[1].od.ptr ;
  484.     p2 = sel2->selbuf ;
  485.     size2 = ( sel2->polys + 31) / 32;
  486.     if (size < size2) size2 = size;
  487.  
  488.     flag = TRUE;
  489.     if (size1 < size2) {
  490.         for (i = 0; i < size1; i++, p1++, p2++) {
  491.             if (*p1 != *p2) {
  492.                 flag = FALSE;
  493.                 break;
  494.             }
  495.         }
  496.         if (flag) {
  497.             for (; i < size2; i++, p2++) {
  498.                 if (*p2 != 0) {
  499.                     flag = FALSE;
  500.                     break;
  501.                 }
  502.             }
  503.         }
  504.     } else {
  505.         for (i = 0; i < size2; i++, p1++, p2++) {
  506.             if (*p1 != *p2) {
  507.                 flag = FALSE;
  508.                 break;
  509.             }
  510.         }
  511.         if (flag) {
  512.             for (; i < size1; i++, p1++) {
  513.                 if (*p1 != 0) {
  514.                     flag = FALSE;
  515.                     break;
  516.                 }
  517.             }
  518.         }
  519.     }
  520.     if (ident == OPE_EQ) {
  521.         StackPushBoolean(flag);
  522.     } else {
  523.         StackPushBoolean(!flag);
  524.     }
  525.     return RETURN_RETURN ;
  526. }
  527.  
  528. static    int        FuncToString( ident, args, buf )
  529. int        ident ;
  530. int        args ;
  531. DataStruct    *buf ;
  532. {
  533.     char    *p ;
  534.     int        *p1;
  535.     int        i, size ;
  536.     SelectClass    *sel1;
  537.     StringClass *str;
  538.  
  539.     sel1 = (SelectClass*)buf[0].od.ptr ;
  540.     p1 = sel1->selbuf ;
  541.     size = ( sel1->size - sizeof( SelectClass ) ) / sizeof( int ) ;
  542.  
  543.     str = StringAlloc(size * 32);
  544.     p = str->str;
  545.  
  546.     for (i = 0; i < size; i++) {
  547.         int j, k;
  548.         k = p1[i];
  549.         for (j = 0; j < 32; ++j) {
  550.             if (k & 1) {
  551.                 *p++ = '1';
  552.             } else {
  553.                 *p++ = '0';
  554.             }
  555.             k /= 2;
  556.         }
  557.     }
  558.     *p++ = '\0';
  559.  
  560.     buf = StackAlloc( 1 );
  561.     buf->type = TYPE_OBJECT ;
  562.     buf->od.ptr = (Object*)str ;
  563.     return RETURN_RETURN ;
  564. }
  565.  
  566.