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 >
Wrap
C/C++ Source or Header
|
1996-03-18
|
11KB
|
605 lines
/*
* ポリゴンの編集処理
*
* Copyright T.Kobayashi 1994.7.17
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "data.h"
#include "poly.h"
#include "view.h"
#define swap( a, b ) { int _w ; _w = a ; a = b ; b = _w ; }
int Selects ;
static void SelectPoly( Polygon*, int, int, int );
/* ポリゴンのセレクト(すべて) */
void PolySelectAll( flag, sw )
int flag ; /* TRUE | FALSE */
int sw ; /* AND | OR */
{
Polygon *poly ;
PolyPtr = NULL ;
Selects = 0 ;
poly = PolyTop();
while( poly != NULL )
{
SelectPoly( poly, TRUE, flag, sw );
poly = BufferNext( poly );
}
}
/* ポリゴンのセレクト(境界指定) */
void PolySelectArea( flag, sw, pos1, pos2 )
int flag ; /* ON | OFF */
int sw ; /* AND | OR */
Vertex *pos1, *pos2 ;
{
int i ;
Polygon *poly ;
Vertex *ver ;
int mode ;
mode = sw & SELECT_SUB ;
sw &= SELECT_LOG ;
PolyPtr = NULL ;
#if 0
printf( "PolySelectArea ( %d, %d, %d )-( %d, %d, %d )\n",
pos1->x, pos1->y, pos1->z, pos2->x, pos2->y, pos2->z );
#endif
if ( pos1->x > pos2->x )
swap( pos1->x, pos2->x );
if ( pos1->y > pos2->y )
swap( pos1->y, pos2->y );
if ( pos1->z > pos2->z )
swap( pos1->z, pos2->z );
#if 0
if ( pos1->x == pos2->x )
{
pos1->x = -32767 ;
pos2->x = 32767 ;
}
if ( pos1->y == pos2->y )
{
pos1->y = -32767 ;
pos2->y = 32767 ;
}
if ( pos1->z == pos2->z )
{
pos1->z = -32767 ;
pos2->z = 32767 ;
}
#endif
Selects = 0 ;
poly = PolyTop();
while( poly != NULL )
{
ver = poly->ver ;
for( i = poly->vers ; i > 0 ; i-- )
{
if ( pos1->x <= ver->x && ver->x <= pos2->x &&
pos1->y <= ver->y && ver->y <= pos2->y &&
pos1->z <= ver->z && ver->z <= pos2->z )
{
if ( mode == SELECT_SUB )
break ;
}
else
{
if ( mode == SELECT_ALL )
break ;
}
ver++ ;
}
SelectPoly( poly, ( i == 0 ) ^ ( mode == SELECT_SUB ), flag, sw );
poly = BufferNext( poly );
}
}
/* ポリゴンのセレクト(透視図で指定) */
void PolySelectPers( flag, sw, x1, y1, x2, y2 )
int flag ; /* ON | OFF */
int sw ; /* AND | OR */
int x1, y1, x2, y2 ;
{
int i ;
Polygon *poly ;
Vertex *ver ;
int scr[2] ;
int mode ;
mode = sw & SELECT_SUB ;
sw &= SELECT_SUB - 1 ;
PolyPtr = NULL ;
x1 = ((x1 * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.x + WinPers.h / 2 ;
y1 = - ((y1 * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.y + WinPers.v / 2 ;
x2 = ((x2 * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.x + WinPers.h / 2 ;
y2 = - ((y2 * WinPers.h) >> CURSOR_2D_SHIFT) + WinPers.y + WinPers.v / 2 ;
if ( x1 > x2 )
swap( x1, x2 );
if ( y1 > y2 )
swap( y1, y2 );
Selects = 0 ;
poly = PolyTop();
while( poly != NULL )
{
ver = poly->ver ;
for( i = poly->vers ; i > 0 ; i-- )
{
if ( ToScreenPers( scr, ver ) && x1-1 <= scr[0] && scr[0] <= x2+1 && y1-1 <= scr[1] && scr[1] <= y2+1 )
{
if ( mode == SELECT_SUB )
break ;
}
else
{
if ( mode == SELECT_ALL )
break ;
}
ver++ ;
}
SelectPoly( poly, ( i == 0 ) ^ ( mode == SELECT_SUB ), flag, sw );
poly = PolyNext( poly );
}
}
/* アトリビュートをセレクト */
void PolySelectAttr( atrno, flag, sw )
int atrno, flag, sw ;
{
Polygon *poly ;
PolyPtr = NULL ;
Selects = 0 ;
poly = PolyTop();
while( poly != NULL )
{
SelectPoly( poly, poly->atr == atrno, flag, sw );
poly = BufferNext( poly );
}
}
/* オブジェクトをセレクト */
void PolySelectObj( objno, flag, sw )
int objno, flag, sw ;
{
Polygon *poly ;
PolyPtr = NULL ;
Selects = 0 ;
poly = PolyTop();
while( poly != NULL )
{
SelectPoly( poly, poly->obj == objno, flag, sw );
poly = BufferNext( poly );
}
}
/* オブジェクトをセレクト */
void PolySelectPolyType( type, flag, sw )
int type, flag, sw ;
{
Polygon *poly ;
PolyPtr = NULL ;
Selects = 0 ;
poly = PolyTop();
while( poly != NULL )
{
SelectPoly( poly, poly->type == type, flag, sw );
poly = BufferNext( poly );
}
}
/* セレクトしているポリゴンのボックスを得る */
int SelectBox( min, max )
Vertex *min ;
Vertex *max ;
{
int i, flag ;
Polygon *poly ;
Vertex *ver ;
flag = FALSE ;
poly = PolyTop();
min->x = min->y = min->z = 32767 ;
max->x = max->y = max->z = -32767 ;
while( poly != NULL )
{
if ( poly->select == ON )
{
ver = poly->ver ;
for( i = poly->vers ; i > 0 ; i-- )
{
if ( min->x > ver->x )
min->x = ver->x ;
if ( min->y > ver->y )
min->y = ver->y ;
if ( min->z > ver->z )
min->z = ver->z ;
if ( max->x < ver->x )
max->x = ver->x ;
if ( max->y < ver->y )
max->y = ver->y ;
if ( max->z < ver->z )
max->z = ver->z ;
ver ++ ;
}
flag = TRUE ;
}
poly = PolyNext( poly );
}
return flag ;
}
static void SelectPoly( poly, sel, flag, sw )
Polygon *poly ;
int sel ;
int flag ; /* ON | OFF */
int sw ; /* UPDATE | AND | OR | XOR */
{
if ( poly->mode & MODE_INVISIBLE )
return ;
if ( ! sel )
flag = ! flag ;
switch( sw & SELECT_LOG )
{
case SELECT_UPDATE:
poly->select = flag ;
break ;
case SELECT_AND:
poly->select &= flag ;
break ;
case SELECT_OR:
poly->select |= flag ;
break ;
case SELECT_XOR:
poly->select ^= flag ;
break ;
default:
assert( FALSE );
}
if ( poly->select )
Selects ++ ;
}
/* セレクト状態を保存する */
void SelectSave( sel )
SelectClass *sel ;
{
Polygon *poly ;
int bit, polys ;
int *buf ;
polys = 0 ;
buf = sel->selbuf ;
bit = 1 ;
*buf = 0 ;
poly = PolyTop();
while( poly != NULL )
{
polys ++ ;
if ( poly->select )
*buf |= bit ;
if ( bit == 0x80000000 )
{
bit = 1 ;
buf++ ;
*buf = 0 ;
}
else
bit <<= 1 ;
poly = BufferNext( poly );
}
sel->polys = polys ;
}
/* カレントポリゴンのセレクトを作る */
void SelectCurrent( sel )
SelectClass *sel ;
{
Polygon *poly ;
int bit, polys ;
int *buf ;
polys = 0 ;
buf = sel->selbuf ;
bit = 1 ;
*buf = 0 ;
poly = PolyTop();
while( poly != NULL )
{
polys ++ ;
if ( poly == PolyPtr )
*buf |= bit ;
if ( bit == 0x80000000 )
{
bit = 1 ;
buf++ ;
*buf = 0 ;
}
else
bit <<= 1 ;
poly = BufferNext( poly );
}
sel->polys = polys ;
}
/* セレクト状態の保存を復帰する */
void SelectLoad( sel )
SelectClass *sel ;
{
Polygon *poly ;
int bit, polys ;
int *buf ;
PolyPtr = NULL ;
buf = sel->selbuf ;
bit = 1 ;
Selects = 0 ;
polys = sel->polys ;
poly = PolyTop();
while( poly != NULL )
{
if ( ( *buf & bit ) && ( polys > 0 ) )
{
poly->select = ON ;
Selects ++ ;
}
else
poly->select = OFF ;
if ( bit == 0x80000000 )
{
bit = 1 ;
buf++ ;
}
else
bit <<= 1 ;
poly = BufferNext( poly );
polys -- ;
}
}
/* セレクト状態の中からn番目のポリゴンだけをセレクトする */
int SelectNumber( sel, n )
SelectClass *sel ;
int n ;
{
Polygon *poly ;
int bit ;
int *buf ;
PolyPtr = NULL ;
if ( n < 0 )
return FALSE ;
buf = sel->selbuf ;
bit = 1 ;
Selects = 0 ;
poly = PolyTop();
while( poly != NULL )
{
if ( *buf & bit )
{
if ( n == 0 )
{
poly->select = ON ;
Selects ++ ;
}
else
poly->select = OFF ;
n -- ;
}
else
poly->select = OFF ;
if ( bit == 0x80000000 )
{
bit = 1 ;
buf++ ;
}
else
bit <<= 1 ;
poly = BufferNext( poly );
}
return n < 0 ;
}
/* セレクト状態のn番目のポリゴンを返す */
Polygon *GetSelectPolyNumber( sel, n )
SelectClass *sel ;
int n ;
{
Polygon *poly ;
int bit ;
int *buf ;
if ( n < 0 )
return FALSE ;
buf = sel->selbuf ;
bit = 1 ;
poly = PolyTop();
while( poly != NULL )
{
if ( *buf & bit )
{
if ( n == 0 )
{
return poly;
}
n -- ;
}
if ( bit == 0x80000000 )
{
bit = 1 ;
buf++ ;
}
else
bit <<= 1 ;
poly = BufferNext( poly );
}
return NULL;
}
/* セレクトのポリゴン数 */
int SelectPolygons( sel )
SelectClass *sel ;
{
Polygon *poly ;
int bit, polys ;
int *buf ;
int s;
buf = sel->selbuf ;
s = 0;
bit = 1 ;
poly = PolyTop();
for (polys = sel->polys; polys > 0; polys--) {
if (*buf & bit)
s ++ ;
if ( bit == 0x80000000 )
{
bit = 1 ;
buf++ ;
}
else
bit <<= 1 ;
}
return s;
}
/* セレクトされているポリゴン削除する */
void PolySelectDelete( sel )
SelectClass *sel ;
{
Polygon *poly, *next ;
int bit, polys ;
int *buf ;
buf = sel->selbuf ;
bit = 1 ;
poly = PolyTop();
polys = sel->polys;
Selects = 0 ;
while( poly != NULL && polys > 0)
{
next = PolyNext( poly );
if ( *buf & bit ) {
ObjData[poly->obj].edit = TRUE ;
BufferDelete( poly );
} else if (poly->select == ON) {
Selects ++ ;
}
if ( bit == 0x80000000 )
{
bit = 1 ;
buf++ ;
}
else
bit <<= 1 ;
poly = next;
polys--;
}
while (poly != NULL) {
if (poly->select == ON) {
Selects ++ ;
}
poly = PolyNext(poly);
}
BufferDeleteCorrect();
}
/* セレクトされているポリゴンに隣接するポリゴンを選択する */
void SelectAdjoint( seldst, selsrc )
SelectClass *seldst, *selsrc ;
{
int i, j;
Polygon *dstpoly, *srcpoly ;
int dstbit, srcbit, polys ;
int *dstbuf, *srcbuf;
int flag;
Vertex *srcver, *dstver ;
polys = 0 ;
dstbuf = seldst->selbuf ;
dstbit = 1 ;
*dstbuf = 0 ;
dstpoly = PolyTop();
while( dstpoly != NULL )
{
flag = FALSE;
srcbuf = selsrc->selbuf ;
srcbit = 1 ;
srcpoly = PolyTop();
if ((dstpoly->mode & MODE_INVISIBLE) == 0) {
while( srcpoly != NULL )
{
if ((srcpoly->mode & MODE_INVISIBLE) == 0 && (*srcbuf & srcbit) != 0) {
srcver = srcpoly->ver ;
for (i = srcpoly->vers ; i > 0 ; i--) {
dstver = dstpoly->ver;
for (j = dstpoly->vers; j > 0; j--) {
if (srcver->x == dstver->x
&& srcver->y == dstver->y
&& srcver->z == dstver->z) {
flag = TRUE;
break;
}
dstver++;
}
if (flag) break;
srcver++;
}
if (flag) break;
}
if ( srcbit == 0x80000000 )
{
srcbit = 1 ;
srcbuf++ ;
}
else
srcbit <<= 1 ;
srcpoly = BufferNext( srcpoly );
}
}
polys ++ ;
if ( flag )
*dstbuf |= dstbit ;
if ( dstbit == 0x80000000 )
{
dstbit = 1 ;
dstbuf++ ;
*dstbuf = 0 ;
}
else
dstbit <<= 1 ;
dstpoly = BufferNext( dstpoly );
}
seldst->polys = polys ;
}