home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / POLYEDIT.LZH / MODEL / EDGELIB.C < prev    next >
C/C++ Source or Header  |  1996-04-03  |  10KB  |  398 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 "view.h"
  20.  
  21. int        EdgeClassID ;
  22. static int    VertexClassID;
  23. static int    MatrixClassID;
  24.  
  25. static    int        FuncEdge(int ident, int args, DataStruct *buf);
  26. static    int        FuncToString(int ident, int args, DataStruct *buf);
  27. static    int        FuncEdge2Select(int ident, int args, DataStruct *buf);
  28. static    int        FuncSelect2Edge(int ident, int args, DataStruct *buf);
  29. static    int        FuncEdges(int ident, int args, DataStruct *buf);
  30. static    int        FuncEdgeGetVertex(int ident, int args, DataStruct *buf);
  31. static    int        FuncEdgeGetCount(int ident, int args, DataStruct *buf);
  32. static    int        FuncEdgeVertex(int ident, int args, DataStruct *buf);
  33. static    int        FuncEdgeSelectCount(int ident, int args, DataStruct *buf);
  34. static    int        FuncDrawEdge(int ident, int args, DataStruct *buf);
  35. static    int        FuncEdgeEqual(int ident, int args, DataStruct *buf);
  36. static    int        FuncEdgeLogical(int ident, int args, DataStruct    *buf);
  37. static    int        FuncEdgeMulMatrix(int ident, int args, DataStruct    *buf);
  38.  
  39. void    EdgeLibInit()
  40. {
  41.     EdgeClassID = NewClass( "Edge", 0 );
  42.     VertexClassID = ClassName("Vertex");
  43.     MatrixClassID = ClassName("Matrix");
  44.  
  45.     NewFunction( 0, "Edge", FuncEdge );
  46.     NewFunction( 0, "EdgeSelect", FuncSelect2Edge );
  47.     NewFunction( EdgeClassID, "tostring", FuncToString );
  48.     NewFunction( EdgeClassID, "EdgeSelect", FuncEdge2Select );
  49.     NewFunction( EdgeClassID, "Edges", FuncEdges );
  50.     NewFunction( EdgeClassID, "EdgeGetVertex", FuncEdgeGetVertex );
  51.     NewFunction( EdgeClassID, "EdgeGetCount", FuncEdgeGetCount );
  52.     NewFunction( EdgeClassID, "EdgeVertex", FuncEdgeVertex );
  53.     NewFunction( EdgeClassID, "EdgeSelectCount", FuncEdgeSelectCount );
  54.     NewFunction( EdgeClassID, "DrawEdge", FuncDrawEdge );
  55.     NewOperator( EdgeClassID, OPE_EQ, FuncEdgeEqual );
  56.     NewOperator( EdgeClassID, OPE_NOTEQ, FuncEdgeEqual );
  57.     NewOperator( EdgeClassID, OPE_AND, FuncEdgeLogical );
  58.     NewOperator( EdgeClassID, OPE_OR, FuncEdgeLogical );
  59.     NewOperator( EdgeClassID, OPE_XOR, FuncEdgeLogical );
  60.     NewOperator( EdgeClassID, OPE_MULT, FuncEdgeLogical );
  61.     NewOperator( EdgeClassID, OPE_PLUS, FuncEdgeLogical );
  62.     NewOperator( EdgeClassID, OPE_MINUS, FuncEdgeLogical );
  63. }
  64.  
  65.  
  66. /*    エッジを生成する    */
  67. static    int        FuncEdge( ident, args, buf )
  68. int        ident ;
  69. int        args ;
  70. DataStruct    *buf ;
  71. {
  72.     EdgeClass *edge;
  73.     if (args == 0) {
  74.         edge = EdgeAlloc(0);
  75.     } else if (args == 2
  76.      && ObjectCheck( &buf[0], VertexClassID )
  77.      &&    ObjectCheck( &buf[1], VertexClassID )) {
  78.         edge = EdgeAlloc(0);
  79.         edge = EdgeAppend(edge,
  80.                         &(((VertexClass*)(buf[0].od.ptr))->ver),
  81.                         &(((VertexClass*)(buf[1].od.ptr))->ver));
  82.     } else {
  83.         ExecError("Edge:引数の型が異なる\n");
  84.     }
  85.     buf = StackAlloc( 1 );
  86.     buf->type = TYPE_OBJECT ;
  87.     buf->od.ptr = (Object*)edge ;
  88.     return RETURN_RETURN ;
  89. }
  90.  
  91. /*    エッジからポリゴンを選択    */
  92. static    int        FuncToString( ident, args, buf )
  93. int        ident ;
  94. int        args ;
  95. DataStruct    *buf ;
  96. {
  97.     char *p;
  98.     EdgeClass *edge;
  99.     EdgeData *ed;
  100.     StringClass *str;
  101.     int i, size;
  102.     ArgCheck( "tostring", args, buf, TYPE_OBJECT, TYPE_NOASN );
  103.     edge = (EdgeClass*)buf[0].od.ptr;
  104.     size = 32 * edge->edges + 1;
  105.     str = StringAlloc(50 * edge->edges + 1);
  106.     p = str->str;
  107.     ed = edge->edge;
  108.     for (i = 0; i < edge->edges; i++) {
  109.         sprintf(p, "(%6d,%6d,%6d)-(%6d,%6d,%6d):%3d\n",
  110.                     ed->x1, ed->y1, ed->z1, ed->x2, ed->y2, ed->z2, ed->count);
  111.         ed++;
  112.     }
  113.     buf = StackAlloc( 1 );
  114.     buf->type = TYPE_OBJECT ;
  115.     buf->od.ptr = (Object*)str ;
  116.     return RETURN_RETURN ;
  117. }
  118.  
  119. /*    エッジからポリゴンを選択    */
  120. static    int        FuncEdge2Select( ident, args, buf )
  121. int        ident ;
  122. int        args ;
  123. DataStruct    *buf ;
  124. {
  125.     ArgCheck( "EdgeSelect", args, buf, TYPE_OBJECT, TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_NOASN );
  126.     PolySelectEdge( (EdgeClass*)(buf[0].od.ptr), buf[1].id.i, buf[2].id.i );
  127.     return RETURN_VOID ;
  128. }
  129.  
  130. /*    エッジを生成する    */
  131. static    int        FuncSelect2Edge( ident, args, buf )
  132. int        ident ;
  133. int        args ;
  134. DataStruct    *buf ;
  135. {
  136.     EdgeClass *edge;
  137.     if (args > 0) {
  138.         ExecError("EdgeSelect:引数の型が異なる\n");
  139.     }
  140.     edge = EdgeSelect();
  141.  
  142.     buf = StackAlloc( 1 );
  143.     buf->type = TYPE_OBJECT ;
  144.     buf->od.ptr = (Object*)edge ;
  145.  
  146.     return RETURN_RETURN ;
  147. }
  148.  
  149. /*    エッジ数    */
  150. static    int        FuncEdges( ident, args, buf )
  151. int        ident ;
  152. int        args ;
  153. DataStruct    *buf ;
  154. {
  155.     ArgCheck( "Edges", args, buf, TYPE_OBJECT, TYPE_NOASN );
  156.     StackPushInt( ((EdgeClass*)(buf[0].od.ptr))->edges );
  157.  
  158.     return RETURN_RETURN ;
  159. }
  160.  
  161. /*    エッジ取得    */
  162. static    int        FuncEdgeGetVertex( ident, args, buf )
  163. int        ident ;
  164. int        args ;
  165. DataStruct    *buf ;
  166. {
  167.     int pos;
  168.     EdgeClass *edge;
  169.     VertexClass    *v1, *v2;
  170.     ArgCheck( "EdgeGetVertex", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_ARRAY, TYPE_NOASN );
  171.  
  172.     if ( buf[2].ad.size < 2 )
  173.         ExecError( "引数配列のサイズが不正です。( Vertex:Position )" );
  174.  
  175.     edge = (EdgeClass*)buf[0].od.ptr ;
  176.     pos = buf[1].id.i;
  177.     buf = buf[2].ad.ary ;
  178.  
  179.     if (0 <= pos && pos < edge->edges) {
  180.         v1 = (VertexClass*)ObjectAlloc( sizeof( VertexClass ), VertexClassID );
  181.         v2 = (VertexClass*)ObjectAlloc( sizeof( VertexClass ), VertexClassID );
  182.         v1->dtype = v2->dtype = POLY_SIMPLE;
  183.         v1->ver.x = edge->edge[pos].x1;
  184.         v1->ver.y = edge->edge[pos].y1;
  185.         v1->ver.z = edge->edge[pos].z1;
  186.         v2->ver.x = edge->edge[pos].x2;
  187.         v2->ver.y = edge->edge[pos].y2;
  188.         v2->ver.z = edge->edge[pos].z2;
  189.  
  190.         if (buf[0].type == TYPE_OBJECT) ObjectFree(buf[0].od.ptr);
  191.         if (buf[1].type == TYPE_OBJECT) ObjectFree(buf[1].od.ptr);
  192.         buf[0].type = buf[1].type = TYPE_OBJECT ;
  193.         buf[0].od.ptr = (Object*)v1;
  194.         buf[1].od.ptr = (Object*)v2;
  195.     }
  196.     return RETURN_VOID ;
  197. }
  198.  
  199. /*    エッジ取得    */
  200. static    int        FuncEdgeGetCount( ident, args, buf )
  201. int        ident ;
  202. int        args ;
  203. DataStruct    *buf ;
  204. {
  205.     int pos;
  206.     EdgeClass *edge;
  207.  
  208.     edge = (EdgeClass*)buf[0].od.ptr ;
  209.  
  210.     if (args == 3
  211.      && ObjectCheck( &buf[1], VertexClassID )
  212.      &&    ObjectCheck( &buf[2], VertexClassID )) {
  213.         pos = EdgeSearch(edge, (Vertex*)(buf[1].od.ptr), (Vertex*)(buf[2].od.ptr));
  214.     } else if (args == 2 && buf[1].type == TYPE_INT) {
  215.         pos = buf[1].id.i;
  216.     } else {
  217.         ExecError("EdgeGetCount:引数の型が異なる\n");
  218.     }
  219.  
  220.     if (0 <= pos && pos < edge->edges) {
  221.         StackPushInt(edge->edge[pos].count);
  222.     } else {
  223.         StackPushInt(0);
  224.     }
  225.     return RETURN_RETURN ;
  226. }
  227.  
  228. /*    頂点が属するエッジを抽出    */
  229. static    int        FuncEdgeVertex( ident, args, buf )
  230. int        ident ;
  231. int        args ;
  232. DataStruct    *buf ;
  233. {
  234.     EdgeClass *ret;
  235.     if ( args != 2 || ObjectCheck( &buf[1], VertexClassID ) == FALSE ) {
  236.         ExecError( "引数の型が不正です(EdgeVertex)" );
  237.     }
  238.  
  239.     ret = (EdgeClass*)ObjectDup(buf[0].od.ptr);
  240.     ret = EdgeSelectVertex(ret, &(((VertexClass*)ObjectDup(buf[1].od.ptr))->ver));
  241.  
  242.     buf = StackAlloc( 1 );
  243.     buf->type = TYPE_OBJECT ;
  244.     buf->od.ptr = (Object*)ret ;
  245.  
  246.     return RETURN_RETURN ;
  247. }
  248.  
  249. /*    ある参照数のエッジを抽出    */
  250. static    int        FuncEdgeSelectCount( ident, args, buf )
  251. int        ident ;
  252. int        args ;
  253. DataStruct    *buf ;
  254. {
  255.     int begin, end;
  256.     EdgeClass *ret;
  257.     if (args == 2) {
  258.         ArgCheck( "EdgeSelectCount", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
  259.         end = 9999;
  260.     } else if (args == 3) {
  261.         ArgCheck( "EdgeSelectCount", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_INT, TYPE_NOASN );
  262.         end = buf[2].id.i;
  263.     } else {
  264.         ExecError( "引数の型が不正です(EdgeSelectCount)" );
  265.     }
  266.     begin = buf[1].id.i;
  267.  
  268.     ret = (EdgeClass*)ObjectDup(buf[0].od.ptr);
  269.     ret = EdgeSelectCount(ret, begin, end);
  270.  
  271.     buf = StackAlloc( 1 );
  272.     buf->type = TYPE_OBJECT ;
  273.     buf->od.ptr = (Object*)ret ;
  274.  
  275.     return RETURN_RETURN ;
  276. }
  277.  
  278. /*    エッジを描画    */
  279. static    int        FuncDrawEdge( ident, args, buf )
  280. int        ident ;
  281. int        args ;
  282. DataStruct    *buf ;
  283. {
  284.     EdgeClass *edge;
  285.     int color;
  286.     if (args == 2) {
  287.         ArgCheck( "EdgeSelectCount", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
  288.         color = buf[1].id.i;
  289.     } else {
  290.         ArgCheck( "EdgeSelectCount", args, buf, TYPE_OBJECT, TYPE_NOASN );
  291.         color = CURSOR_COLOR;
  292.     }
  293.     edge = (EdgeClass*)(buf[0].od.ptr);
  294.  
  295.     DrawEdge(edge, color);
  296.  
  297.     return RETURN_VOID ;
  298. }
  299.  
  300. /*    エッジの等価判定    */
  301. static    int        FuncEdgeEqual( ident, args, buf )
  302. int        ident ;
  303. int        args ;
  304. DataStruct    *buf ;
  305. {
  306.     EdgeClass    *edge1, *edge2 ;
  307.  
  308.     if ( args != 2 || ObjectCheck( &buf[1], EdgeClassID ) == FALSE ) {
  309.         ExecError( "論理演算の型が不正です(Edge)" );
  310.     }
  311.     edge1 = (EdgeClass*)buf[0].od.ptr ;
  312.     edge2 = (EdgeClass*)buf[1].od.ptr ;
  313.  
  314.     if (ident == OPE_EQ)
  315.         StackPushBoolean(EdgeLogicalEqual(edge1, edge2) );
  316.     else
  317.         StackPushBoolean( ! EdgeLogicalEqual(edge1, edge2) );
  318.  
  319.     return RETURN_RETURN ;
  320. }
  321.  
  322.  
  323. /*    エッジの論理演算    */
  324. static    int        FuncEdgeLogical( ident, args, buf )
  325. int        ident ;
  326. int        args ;
  327. DataStruct    *buf ;
  328. {
  329.     EdgeClass    *edge1, *edge2, *edge, *ret ;
  330.  
  331.     if (ident == OPE_MULT && args == 2 && ObjectCheck(&buf[1], MatrixClassID)) {
  332.         return FuncEdgeMulMatrix(ident, args, buf);
  333.     }
  334.  
  335.     if ( args != 2 || ObjectCheck( &buf[1], EdgeClassID ) == FALSE ) {
  336.         ExecError( "論理演算の型が不正です(Edge)" );
  337.     }
  338.     edge1 = (EdgeClass*)buf[0].od.ptr ;
  339.     edge2 = (EdgeClass*)buf[1].od.ptr ;
  340.  
  341.     if (ident == OPE_MINUS || edge1->edges > edge2->edges) {
  342.         ret = (EdgeClass*)ObjectDup((Object*)edge1);
  343.         edge = edge2;
  344.     } else {
  345.         ret = (EdgeClass*)ObjectDup((Object*)edge2);
  346.         edge = edge1;
  347.     }
  348.  
  349.     switch( ident ) {
  350.     case OPE_AND:
  351.     case OPE_MULT:
  352.         ret = EdgeLogicalAnd(ret, edge);
  353.         break;
  354.     case OPE_OR:
  355.     case OPE_PLUS:
  356.         ret = EdgeLogicalOr(ret, edge);
  357.         break;
  358.     case OPE_MINUS:
  359.         ret = EdgeLogicalSub(ret, edge);
  360.         break;
  361.     case OPE_XOR:
  362.         ret = EdgeLogicalXor(ret, edge);
  363.     }
  364.  
  365.     buf = StackAlloc( 1 );
  366.     buf->type = TYPE_OBJECT ;
  367.     buf->od.ptr = (Object*)ret ;
  368.  
  369.     return RETURN_RETURN ;
  370. }
  371.  
  372. /*    エッジの論理演算    */
  373. static    int        FuncEdgeMulMatrix( ident, args, buf )
  374. int        ident ;
  375. int        args ;
  376. DataStruct    *buf ;
  377. {
  378.     EdgeClass    *edge, *ret ;
  379.     MatrixClass    *mat;
  380.  
  381.     if ( args != 2 || ObjectCheck( &buf[1], MatrixClassID ) == FALSE ) {
  382.         ExecError( "論理演算の型が不正です(Edge)" );
  383.     }
  384.     edge = (EdgeClass*)buf[0].od.ptr ;
  385.     mat = (MatrixClass*)buf[1].od.ptr ;
  386.  
  387.     ret = (EdgeClass*)ObjectDup((Object*)edge);
  388.     ret = EdgeMulMatrix(ret, mat);
  389.  
  390.     buf = StackAlloc( 1 );
  391.     buf->type = TYPE_OBJECT ;
  392.     buf->od.ptr = (Object*)ret ;
  393.  
  394.     return RETURN_RETURN ;
  395. }
  396.  
  397.  
  398.