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 >
Wrap
C/C++ Source or Header
|
1996-04-03
|
10KB
|
398 lines
/*
* エッジ
*
* Copyright T.Kobayashi 1994.7.9
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "matrix.h"
#include "vector.h"
#include "matclass.h"
#include "strclass.h"
#include "ml.h"
#include "poly.h"
#include "view.h"
int EdgeClassID ;
static int VertexClassID;
static int MatrixClassID;
static int FuncEdge(int ident, int args, DataStruct *buf);
static int FuncToString(int ident, int args, DataStruct *buf);
static int FuncEdge2Select(int ident, int args, DataStruct *buf);
static int FuncSelect2Edge(int ident, int args, DataStruct *buf);
static int FuncEdges(int ident, int args, DataStruct *buf);
static int FuncEdgeGetVertex(int ident, int args, DataStruct *buf);
static int FuncEdgeGetCount(int ident, int args, DataStruct *buf);
static int FuncEdgeVertex(int ident, int args, DataStruct *buf);
static int FuncEdgeSelectCount(int ident, int args, DataStruct *buf);
static int FuncDrawEdge(int ident, int args, DataStruct *buf);
static int FuncEdgeEqual(int ident, int args, DataStruct *buf);
static int FuncEdgeLogical(int ident, int args, DataStruct *buf);
static int FuncEdgeMulMatrix(int ident, int args, DataStruct *buf);
void EdgeLibInit()
{
EdgeClassID = NewClass( "Edge", 0 );
VertexClassID = ClassName("Vertex");
MatrixClassID = ClassName("Matrix");
NewFunction( 0, "Edge", FuncEdge );
NewFunction( 0, "EdgeSelect", FuncSelect2Edge );
NewFunction( EdgeClassID, "tostring", FuncToString );
NewFunction( EdgeClassID, "EdgeSelect", FuncEdge2Select );
NewFunction( EdgeClassID, "Edges", FuncEdges );
NewFunction( EdgeClassID, "EdgeGetVertex", FuncEdgeGetVertex );
NewFunction( EdgeClassID, "EdgeGetCount", FuncEdgeGetCount );
NewFunction( EdgeClassID, "EdgeVertex", FuncEdgeVertex );
NewFunction( EdgeClassID, "EdgeSelectCount", FuncEdgeSelectCount );
NewFunction( EdgeClassID, "DrawEdge", FuncDrawEdge );
NewOperator( EdgeClassID, OPE_EQ, FuncEdgeEqual );
NewOperator( EdgeClassID, OPE_NOTEQ, FuncEdgeEqual );
NewOperator( EdgeClassID, OPE_AND, FuncEdgeLogical );
NewOperator( EdgeClassID, OPE_OR, FuncEdgeLogical );
NewOperator( EdgeClassID, OPE_XOR, FuncEdgeLogical );
NewOperator( EdgeClassID, OPE_MULT, FuncEdgeLogical );
NewOperator( EdgeClassID, OPE_PLUS, FuncEdgeLogical );
NewOperator( EdgeClassID, OPE_MINUS, FuncEdgeLogical );
}
/* エッジを生成する */
static int FuncEdge( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
EdgeClass *edge;
if (args == 0) {
edge = EdgeAlloc(0);
} else if (args == 2
&& ObjectCheck( &buf[0], VertexClassID )
&& ObjectCheck( &buf[1], VertexClassID )) {
edge = EdgeAlloc(0);
edge = EdgeAppend(edge,
&(((VertexClass*)(buf[0].od.ptr))->ver),
&(((VertexClass*)(buf[1].od.ptr))->ver));
} else {
ExecError("Edge:引数の型が異なる\n");
}
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)edge ;
return RETURN_RETURN ;
}
/* エッジからポリゴンを選択 */
static int FuncToString( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
char *p;
EdgeClass *edge;
EdgeData *ed;
StringClass *str;
int i, size;
ArgCheck( "tostring", args, buf, TYPE_OBJECT, TYPE_NOASN );
edge = (EdgeClass*)buf[0].od.ptr;
size = 32 * edge->edges + 1;
str = StringAlloc(50 * edge->edges + 1);
p = str->str;
ed = edge->edge;
for (i = 0; i < edge->edges; i++) {
sprintf(p, "(%6d,%6d,%6d)-(%6d,%6d,%6d):%3d\n",
ed->x1, ed->y1, ed->z1, ed->x2, ed->y2, ed->z2, ed->count);
ed++;
}
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)str ;
return RETURN_RETURN ;
}
/* エッジからポリゴンを選択 */
static int FuncEdge2Select( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
ArgCheck( "EdgeSelect", args, buf, TYPE_OBJECT, TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_NOASN );
PolySelectEdge( (EdgeClass*)(buf[0].od.ptr), buf[1].id.i, buf[2].id.i );
return RETURN_VOID ;
}
/* エッジを生成する */
static int FuncSelect2Edge( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
EdgeClass *edge;
if (args > 0) {
ExecError("EdgeSelect:引数の型が異なる\n");
}
edge = EdgeSelect();
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)edge ;
return RETURN_RETURN ;
}
/* エッジ数 */
static int FuncEdges( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
ArgCheck( "Edges", args, buf, TYPE_OBJECT, TYPE_NOASN );
StackPushInt( ((EdgeClass*)(buf[0].od.ptr))->edges );
return RETURN_RETURN ;
}
/* エッジ取得 */
static int FuncEdgeGetVertex( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int pos;
EdgeClass *edge;
VertexClass *v1, *v2;
ArgCheck( "EdgeGetVertex", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_ARRAY, TYPE_NOASN );
if ( buf[2].ad.size < 2 )
ExecError( "引数配列のサイズが不正です。( Vertex:Position )" );
edge = (EdgeClass*)buf[0].od.ptr ;
pos = buf[1].id.i;
buf = buf[2].ad.ary ;
if (0 <= pos && pos < edge->edges) {
v1 = (VertexClass*)ObjectAlloc( sizeof( VertexClass ), VertexClassID );
v2 = (VertexClass*)ObjectAlloc( sizeof( VertexClass ), VertexClassID );
v1->dtype = v2->dtype = POLY_SIMPLE;
v1->ver.x = edge->edge[pos].x1;
v1->ver.y = edge->edge[pos].y1;
v1->ver.z = edge->edge[pos].z1;
v2->ver.x = edge->edge[pos].x2;
v2->ver.y = edge->edge[pos].y2;
v2->ver.z = edge->edge[pos].z2;
if (buf[0].type == TYPE_OBJECT) ObjectFree(buf[0].od.ptr);
if (buf[1].type == TYPE_OBJECT) ObjectFree(buf[1].od.ptr);
buf[0].type = buf[1].type = TYPE_OBJECT ;
buf[0].od.ptr = (Object*)v1;
buf[1].od.ptr = (Object*)v2;
}
return RETURN_VOID ;
}
/* エッジ取得 */
static int FuncEdgeGetCount( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int pos;
EdgeClass *edge;
edge = (EdgeClass*)buf[0].od.ptr ;
if (args == 3
&& ObjectCheck( &buf[1], VertexClassID )
&& ObjectCheck( &buf[2], VertexClassID )) {
pos = EdgeSearch(edge, (Vertex*)(buf[1].od.ptr), (Vertex*)(buf[2].od.ptr));
} else if (args == 2 && buf[1].type == TYPE_INT) {
pos = buf[1].id.i;
} else {
ExecError("EdgeGetCount:引数の型が異なる\n");
}
if (0 <= pos && pos < edge->edges) {
StackPushInt(edge->edge[pos].count);
} else {
StackPushInt(0);
}
return RETURN_RETURN ;
}
/* 頂点が属するエッジを抽出 */
static int FuncEdgeVertex( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
EdgeClass *ret;
if ( args != 2 || ObjectCheck( &buf[1], VertexClassID ) == FALSE ) {
ExecError( "引数の型が不正です(EdgeVertex)" );
}
ret = (EdgeClass*)ObjectDup(buf[0].od.ptr);
ret = EdgeSelectVertex(ret, &(((VertexClass*)ObjectDup(buf[1].od.ptr))->ver));
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}
/* ある参照数のエッジを抽出 */
static int FuncEdgeSelectCount( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int begin, end;
EdgeClass *ret;
if (args == 2) {
ArgCheck( "EdgeSelectCount", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
end = 9999;
} else if (args == 3) {
ArgCheck( "EdgeSelectCount", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_INT, TYPE_NOASN );
end = buf[2].id.i;
} else {
ExecError( "引数の型が不正です(EdgeSelectCount)" );
}
begin = buf[1].id.i;
ret = (EdgeClass*)ObjectDup(buf[0].od.ptr);
ret = EdgeSelectCount(ret, begin, end);
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}
/* エッジを描画 */
static int FuncDrawEdge( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
EdgeClass *edge;
int color;
if (args == 2) {
ArgCheck( "EdgeSelectCount", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
color = buf[1].id.i;
} else {
ArgCheck( "EdgeSelectCount", args, buf, TYPE_OBJECT, TYPE_NOASN );
color = CURSOR_COLOR;
}
edge = (EdgeClass*)(buf[0].od.ptr);
DrawEdge(edge, color);
return RETURN_VOID ;
}
/* エッジの等価判定 */
static int FuncEdgeEqual( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
EdgeClass *edge1, *edge2 ;
if ( args != 2 || ObjectCheck( &buf[1], EdgeClassID ) == FALSE ) {
ExecError( "論理演算の型が不正です(Edge)" );
}
edge1 = (EdgeClass*)buf[0].od.ptr ;
edge2 = (EdgeClass*)buf[1].od.ptr ;
if (ident == OPE_EQ)
StackPushBoolean(EdgeLogicalEqual(edge1, edge2) );
else
StackPushBoolean( ! EdgeLogicalEqual(edge1, edge2) );
return RETURN_RETURN ;
}
/* エッジの論理演算 */
static int FuncEdgeLogical( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
EdgeClass *edge1, *edge2, *edge, *ret ;
if (ident == OPE_MULT && args == 2 && ObjectCheck(&buf[1], MatrixClassID)) {
return FuncEdgeMulMatrix(ident, args, buf);
}
if ( args != 2 || ObjectCheck( &buf[1], EdgeClassID ) == FALSE ) {
ExecError( "論理演算の型が不正です(Edge)" );
}
edge1 = (EdgeClass*)buf[0].od.ptr ;
edge2 = (EdgeClass*)buf[1].od.ptr ;
if (ident == OPE_MINUS || edge1->edges > edge2->edges) {
ret = (EdgeClass*)ObjectDup((Object*)edge1);
edge = edge2;
} else {
ret = (EdgeClass*)ObjectDup((Object*)edge2);
edge = edge1;
}
switch( ident ) {
case OPE_AND:
case OPE_MULT:
ret = EdgeLogicalAnd(ret, edge);
break;
case OPE_OR:
case OPE_PLUS:
ret = EdgeLogicalOr(ret, edge);
break;
case OPE_MINUS:
ret = EdgeLogicalSub(ret, edge);
break;
case OPE_XOR:
ret = EdgeLogicalXor(ret, edge);
}
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}
/* エッジの論理演算 */
static int FuncEdgeMulMatrix( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
EdgeClass *edge, *ret ;
MatrixClass *mat;
if ( args != 2 || ObjectCheck( &buf[1], MatrixClassID ) == FALSE ) {
ExecError( "論理演算の型が不正です(Edge)" );
}
edge = (EdgeClass*)buf[0].od.ptr ;
mat = (MatrixClass*)buf[1].od.ptr ;
ret = (EdgeClass*)ObjectDup((Object*)edge);
ret = EdgeMulMatrix(ret, mat);
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}