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 >
Wrap
C/C++ Source or Header
|
1996-02-29
|
14KB
|
566 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 "menu.h"
#include "graph.h"
#include "input.h"
static int FuncSelectPolygons( int, int, DataStruct* );
static int FuncSelectAll( int, int, DataStruct* );
static int FuncSelectArea( int, int, DataStruct* );
static int FuncSelectPers( int, int, DataStruct* );
static int FuncSelectAttr( int, int, DataStruct* );
static int FuncSelectObj( int, int, DataStruct* );
static int FuncSelectPolyType( int, int, DataStruct* );
static int FuncSelectBox( int, int, DataStruct* );
static int FuncSelectSave( int, int, DataStruct* );
static int FuncSelectLoad( int, int, DataStruct* );
static int FuncSelectAdjoint( int, int, DataStruct* );
static int FuncSelectNumber( int, int, DataStruct* );
static int FuncSelectPolyDelete( int, int, DataStruct* );
static int FuncSelectEqual( int, int, DataStruct* );
static int FuncSelectLogical( int, int, DataStruct* );
static int FuncToString( int, int, DataStruct* );
static int FuncPolyLoad( int, int, DataStruct* );
static int FuncSelectCurrent( int, int, DataStruct* );
int SelectClassID ;
void SelectLibInit()
{
SelectClassID = NewClass( "Select", 0 );
NewFunction( 0, "SelectPolygons", FuncSelectPolygons );
NewFunction( 0, "SelectAll", FuncSelectAll );
NewFunction( 0, "SelectArea", FuncSelectArea );
NewFunction( 0, "SelectPers", FuncSelectPers );
NewFunction( 0, "SelectAttr", FuncSelectAttr );
NewFunction( 0, "SelectObj", FuncSelectObj );
NewFunction( 0, "SelectPolyType", FuncSelectPolyType );
NewFunction( 0, "SelectBox", FuncSelectBox );
NewFunction( 0, "Select", FuncSelectSave );
NewFunction( 0, "SelectCurrent", FuncSelectCurrent );
NewFunction( SelectClassID, "SelectAdjoint", FuncSelectAdjoint );
NewFunction( SelectClassID, "tostring", FuncToString );
NewFunction( SelectClassID, "SelectPolygons", FuncSelectPolygons );
NewFunction( SelectClassID, "Select", FuncSelectLoad );
NewFunction( SelectClassID, "SelectNumber", FuncSelectNumber );
NewFunction( SelectClassID, "PolyDelete", FuncSelectPolyDelete );
NewFunction( SelectClassID, "PolyLoad", FuncPolyLoad );
NewOperator( SelectClassID, OPE_NOT, FuncSelectLogical );
NewOperator( SelectClassID, OPE_AND, FuncSelectLogical );
NewOperator( SelectClassID, OPE_OR, FuncSelectLogical );
NewOperator( SelectClassID, OPE_XOR, FuncSelectLogical );
NewOperator( SelectClassID, OPE_EQ, FuncSelectEqual );
NewOperator( SelectClassID, OPE_NOTEQ, FuncSelectEqual );
}
/* セレクトしているポリゴンの数を得る */
static int FuncSelectPolygons( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
if (args == 0) {
StackPushInt( Selects );
} else {
ArgCheck( "SelectPolygons", args, buf, TYPE_OBJECT, TYPE_NOASN );
StackPushInt( SelectPolygons((SelectClass*)(buf->od.ptr)));
}
return RETURN_RETURN ;
}
/* ポリゴンのセレクト(すべて) */
static int FuncSelectAll( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
if ( args == 1 )
{
ArgCheck( "SelectAll", args, buf, TYPE_INT|TYPE_BOOLEAN, TYPE_NOASN );
PolySelectAll( buf[0].id.i, SELECT_UPDATE );
}
else
{
ArgCheck( "SelectAll", args, buf, TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_NOASN );
PolySelectAll( buf[0].id.i, buf[1].id.i );
}
return RETURN_VOID ;
}
/* ポリゴンのセレクト(境界指定) */
static int FuncSelectArea( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
Vertex *v1, *v2 ;
ArgCheck( "SelectArea", args, buf,
TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_OBJECT, TYPE_OBJECT, TYPE_NOASN );
if ( ObjectCheck( &buf[2], VertexClassID ) == FALSE ||
ObjectCheck( &buf[3], VertexClassID ) == FALSE )
{
ExecError( "引数の型が不正です。(SelectArea)" );
}
v1 = &((VertexClass*)buf[2].od.ptr)->ver ;
v2 = &((VertexClass*)buf[3].od.ptr)->ver ;
PolySelectArea( buf[0].id.i, buf[1].id.i, v1, v2 );
return RETURN_VOID ;
}
/* ポリゴンのセレクト(透視図で指定) */
static int FuncSelectPers( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
ArgCheck( "SelectPers", args, buf,
TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_NOASN );
PolySelectPers( buf[0].id.i, buf[1].id.i,
buf[2].id.i, buf[3].id.i, buf[4].id.i, buf[5].id.i );
return RETURN_VOID ;
}
/* アトリビュートをセレクト */
static int FuncSelectAttr( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
ArgCheck( "SelectAttr", args, buf, TYPE_INT, TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_NOASN );
PolySelectAttr( buf[0].id.i, buf[1].id.i, buf[2].id.i );
return RETURN_VOID ;
}
/* オブジェクトをセレクト */
static int FuncSelectObj( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
ArgCheck( "SelectObj", args, buf, TYPE_INT, TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_NOASN );
PolySelectObj( buf[0].id.i, buf[1].id.i, buf[2].id.i );
return RETURN_VOID ;
}
/* オブジェクトをセレクト */
static int FuncSelectPolyType( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
ArgCheck( "SelectPolyType", args, buf, TYPE_INT, TYPE_INT|TYPE_BOOLEAN, TYPE_INT, TYPE_NOASN );
PolySelectPolyType( buf[0].id.i, buf[1].id.i, buf[2].id.i );
return RETURN_VOID ;
}
/* セレクトしているポリゴンのボックスを得る */
static int FuncSelectBox( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int i ;
VertexClass *min, *max ;
ArgCheck( "SelectBox", args, buf, TYPE_ARRAY, TYPE_NOASN );
if ( buf[0].ad.size < 2 )
ExecError( "引数配列のサイズが不正です。(SelectBox)" );
buf = buf[0].ad.ary ;
for( i = 0 ; i < 2 ; i++ )
{
if ( buf[i].type == TYPE_OBJECT )
ObjectFree( buf[i].od.ptr );
buf[i].type = TYPE_OBJECT ;
}
min = (VertexClass*)ObjectAlloc( sizeof( VertexClass ), VertexClassID );
max = (VertexClass*)ObjectAlloc( sizeof( VertexClass ), VertexClassID );
min->dtype = max->dtype = POLY_SIMPLE ;
buf[0].od.ptr = (Object*)min ;
buf[1].od.ptr = (Object*)max ;
StackPushBoolean( SelectBox( &min->ver, &max->ver ) );
return RETURN_RETURN ;
}
/* セレクト状態を保存する */
static int FuncSelectSave( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int size ;
SelectClass *sel ;
size = ( Polygons() / 32 + 1 ) * sizeof( int ) + sizeof( SelectClass ) ;
sel = (SelectClass*)ObjectAlloc( size, SelectClassID );
SelectSave( sel );
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)sel ;
return RETURN_RETURN ;
}
/* カレントポリゴンのセレクト状態をつくる */
static int FuncSelectCurrent( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int size ;
SelectClass *sel ;
size = ( Polygons() / 32 + 1 ) * sizeof( int ) + sizeof( SelectClass ) ;
sel = (SelectClass*)ObjectAlloc( size, SelectClassID );
SelectCurrent( sel );
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)sel ;
return RETURN_RETURN ;
}
/* セレクト状態の保存を復帰する */
static int FuncSelectLoad( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
ArgCheck( "SelectLoad", args, buf, TYPE_OBJECT, TYPE_NOASN );
SelectLoad( (SelectClass*)buf[0].od.ptr );
StackPush( &buf[0] );
return RETURN_RETURN ;
}
static int FuncSelectAdjoint( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int size;
SelectClass *sel ;
ArgCheck( "SelectAdjoint", args, buf, TYPE_OBJECT, TYPE_NOASN );
size = ( Polygons() / 32 + 1 ) * sizeof( int ) + sizeof( SelectClass ) ;
sel = (SelectClass*)ObjectAlloc( size, SelectClassID );
SelectAdjoint( sel, (SelectClass*)buf[0].od.ptr );
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)sel ;
return RETURN_RETURN ;
}
/* セレクト状態の中からn番目のポリゴンだけをセレクトする */
static int FuncSelectNumber( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
ArgCheck( "SelectNumber", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
StackPushInt( SelectNumber( (SelectClass*)buf[0].od.ptr, buf[1].id.i ) );
return RETURN_RETURN ;
}
static int FuncPolyLoad( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
SelectClass *sel;
int pos;
ArgCheck( "PolyLoad", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
sel = (SelectClass*)buf[0].od.ptr;
pos = buf[1].id.i;
StackPushInt((int)PolyLoadPtr(GetSelectPolyNumber(sel, pos)));
return RETURN_RETURN ;
}
/* セレクト状態の保存を復帰する */
static int FuncSelectPolyDelete( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
ArgCheck( "PolyDelete", args, buf, TYPE_OBJECT, TYPE_NOASN );
PolySelectDelete( (SelectClass*)buf[0].od.ptr );
return RETURN_VOID ;
}
#if 0
/* セレクト状態の論理演算 */
static int FuncSelectLogical( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int *p1, *p2, *pr ;
int i, size ;
SelectClass *sel1, *sel2, *ret ;
sel1 = (SelectClass*)buf[0].od.ptr ;
p1 = sel1->selbuf ;
/*
size = ( sel1->size - sizeof( SelectClass ) ) / sizeof( int ) ;
*/
size = (sel1->polys+31)/32;
if ( args == 2 )
{
if ( ObjectCheck( &buf[1], SelectClassID ) == FALSE )
ExecError( "論理演算の型が不正です(Select)" );
sel2 = (SelectClass*)buf[1].od.ptr ;
p2 = sel2->selbuf ;
}
ret = (SelectClass*)ObjectAlloc(
sizeof( SelectClass ) + size*sizeof( int ), SelectClassID );
pr = ret->selbuf ;
ret->polys = sel1->polys;
for( i = 0 ; i < size ; i++ )
{
switch( ident )
{
case OPE_NOT:
*pr++ = ~ *p1++ ;
break ;
case OPE_AND:
*pr++ = *p1++ & *p2++ ;
break ;
case OPE_OR:
*pr++ = *p1++ | *p2++ ;
break ;
case OPE_XOR:
*pr++ = *p1++ ^ *p2++ ;
break ;
default:
assert( FALSE );
}
}
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}
#else
/* セレクト状態の論理演算 */
static int FuncSelectLogical( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int *p1, *p2, *pr ;
int i, size, size1, size2 ;
SelectClass *sel1, *sel2, *ret ;
size = ( Polygons() + 31) / 32;
sel1 = (SelectClass*)buf[0].od.ptr ;
p1 = sel1->selbuf ;
size1 = ( sel1->polys + 31) / 32;
if (size < size1) size1 = size;
if ( args == 2 )
{
if ( ObjectCheck( &buf[1], SelectClassID ) == FALSE )
ExecError( "論理演算の型が不正です(Select)" );
sel2 = (SelectClass*)buf[1].od.ptr ;
p2 = sel2->selbuf ;
size2 = ( sel2->polys + 31) / 32;
if (size < size2) size2 = size;
}
ret = (SelectClass*)ObjectAlloc(
sizeof( SelectClass ) + size*sizeof( int ), SelectClassID );
ret->polys = Polygons();
pr = ret->selbuf ;
for (i = 0; i < size1; i++) {
*pr++ = *p1++;
}
for (; i < size; i++) {
*pr++ = 0;
}
pr = ret->selbuf ;
switch (ident) {
case OPE_NOT:
for (i = 0; i < size; i++, pr++) {
*pr = ~ *pr;
}
break;
case OPE_AND:
for (i = 0; i < size2; i++,pr++) {
*pr &= *p2++ ;
}
for (; i < size; i++, pr++) {
*pr = 0;
}
break;
case OPE_OR:
for (i = 0; i < size2; i++,pr++) {
*pr |= *p2++ ;
}
break ;
case OPE_XOR:
for (i = 0; i < size2; i++,pr++) {
*pr ^= *p2++ ;
}
break ;
default:
ExecError("演算子が不正です。(SelectClass)");
}
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}
#endif
/* セレクト状態の論理演算 */
static int FuncSelectEqual( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int *p1, *p2;
int i, size, size1, size2 ;
SelectClass *sel1, *sel2;
int flag;
size = ( Polygons() + 31) / 32;
if (args != 2 || ObjectCheck( &buf[1], SelectClassID ) == FALSE ) {
ExecError( "論理演算の型が不正です(Select)" );
}
sel1 = (SelectClass*)buf[0].od.ptr ;
p1 = sel1->selbuf ;
size1 = ( sel1->polys + 31) / 32;
if (size < size1) size1 = size;
sel2 = (SelectClass*)buf[1].od.ptr ;
p2 = sel2->selbuf ;
size2 = ( sel2->polys + 31) / 32;
if (size < size2) size2 = size;
flag = TRUE;
if (size1 < size2) {
for (i = 0; i < size1; i++, p1++, p2++) {
if (*p1 != *p2) {
flag = FALSE;
break;
}
}
if (flag) {
for (; i < size2; i++, p2++) {
if (*p2 != 0) {
flag = FALSE;
break;
}
}
}
} else {
for (i = 0; i < size2; i++, p1++, p2++) {
if (*p1 != *p2) {
flag = FALSE;
break;
}
}
if (flag) {
for (; i < size1; i++, p1++) {
if (*p1 != 0) {
flag = FALSE;
break;
}
}
}
}
if (ident == OPE_EQ) {
StackPushBoolean(flag);
} else {
StackPushBoolean(!flag);
}
return RETURN_RETURN ;
}
static int FuncToString( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
char *p ;
int *p1;
int i, size ;
SelectClass *sel1;
StringClass *str;
sel1 = (SelectClass*)buf[0].od.ptr ;
p1 = sel1->selbuf ;
size = ( sel1->size - sizeof( SelectClass ) ) / sizeof( int ) ;
str = StringAlloc(size * 32);
p = str->str;
for (i = 0; i < size; i++) {
int j, k;
k = p1[i];
for (j = 0; j < 32; ++j) {
if (k & 1) {
*p++ = '1';
} else {
*p++ = '0';
}
k /= 2;
}
}
*p++ = '\0';
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)str ;
return RETURN_RETURN ;
}