home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
POLYEDIT.LZH
/
MACRO
/
EDITD.M
< prev
next >
Wrap
Text File
|
1996-07-06
|
19KB
|
1,013 lines
//
// 2点を指定して面を分割する
//
function SeparatePolygons()
{
var point[2];
var key;
var sel, sels, work_sel;
var vers, i, j, k;
var flag, temp;
var pick, draw_flag = ON;
var v[MAXVERTEX];
if( SelectPolygons() == 0 )
{
Warning();
if( MESSAGE == ON )
Message( error_msg3 );
return;
}
sel = Select();
point[0] = Cursor();
SelectArea( TRUE, SELECT_AND | SELECT_SUB, point[0], point[0] );
work_sel = Select();
if( SelectPolygons() == 0 )
{
Warning();
Select( sel );
if( MESSAGE == ON )
{
temp = PolyVertex( point[0] );
if( temp == point[0] )
Message( error_msg2 );
else
Message( error_msg1 );
}
return;
}
Select( sel );
PushMenu();
Status_org = Status_title;
MenuPosition( Menu( " 動作設定(&S)",
"分割中止 ESC", MenuQuit
), Menu_Title );
ClearStatus();
Status_title[0] = "【面分割中】";
DrawStatus();
quit_flag = FALSE;
cur = Cursor();
pick = cur;
input_flag = OFF;
while( TRUE )
{
if( draw_flag == ON )
DrawLine( point[0], cur );
key = WaitEvent();
if( key )
input_flag = ON;
if( ( ShiftStat() & 1 ) == 1 )
{
cur = Cursor();
TrimCursor(point[0], MouseWindow());
Cursor( cur );
}
else
cur = Cursor();
key = KeyCode();
if( input_flag | key == INPUT_KEY )
{
if( cur == point[0] )
{
Warning();
if( MESSAGE == ON )
Message( "2点目は生成する辺を指定してください" );
}
else
{
Select( work_sel );
SelectArea( TRUE, SELECT_AND | SELECT_SUB, cur, cur );
if( SelectPolygons() == 0 )
{
Warning();
if( MESSAGE == ON )
{
temp = PolyVertex( cur );
if( temp != cur )
Message( error_msg1 );
else
Message( "選択面中にこの2点で分割される面は存在しません" );
}
Select( sel );
}
else
{
point[1] = cur;
break;
}
}
}
else if( key == ESC | key == BS | quit_flag == TRUE )
{
PopandClear( OVERWRITE );
Select( sel );
return;
}
else
KeyProcess( key );
if( ((key!=0 ) & (key != INPUT_KEY)) | ( pick != Cursor()) )
{
draw_flag = ON;
DrawLine( point[0], pick );
}
else
draw_flag = OFF;
pick = Cursor();
input_flag = OFF;
}
Clear( OVERWRITE );
work_sel = Select();
EdgeSelect( Edge( point[0], point[1]), FALSE, SELECT_AND );
if( SelectPolygons() == 0 )
{
PopandClear( OVERWRITE );
if( MESSAGE == ON )
Message( "選択面中にこの2点で分割される面は存在しません\n"
+"最初から選択しなおしてください" );
Select( sel );
return;
}
sels = SelectPolygons();
for( i = 0; i< sels; i++ )
{
PolyLoad( work_sel, i );
vers = PolyVertexs();
flag = OFF;
j = 0;
k = 0;
while( TRUE )
{
temp = PolyGetVertex( j );
if( flag == ON )
{
v[k] = temp;
k++;
if( temp == point[0] | temp == point[1] )
break;
else
PolyDelVertex( j );
}
else
{
if( temp == point[0] | temp == point[1] )
{
flag = ON;
v[k] = temp;
k++;
}
j++;
}
}
PolySave();
for( j = 0;j<k;j++ )
PolySetVertex( v[j], j );
PolyVertexs( k );
if( SelectPolygons( sel ) == 0 )
{
PolyAppend( FALSE );
ViewCursor( OFF );
DrawCurrent( FALSE );
ViewCursor( ON );
}
else
{
PolyAppend( TRUE );
ViewCursor( OFF );
DrawCurrent( TRUE );
ViewCursor( ON );
}
}
Select( Select() | sel );
// Update( OVERWRITE );
UpdateObject();
PopMenu();
Status_title = Status_org;
DrawStatus();
}
//
// 2点を指定して面を合成する
//
function JointPolygons()
{
var point[2];
var key, temp;
var sel, sels, work_sel;
var i, j;
var ty1, ty2, vers1, vers2, flag1, flag2, temp1, temp2;
var v[MAXVERTEX];
var pick, draw_flag = ON;
if( SelectPolygons() == 0 )
{
Warning();
if( MESSAGE == ON )
Message( error_msg3 );
return;
}
sel = Select();
point[0] = Cursor();
SelectArea( TRUE, SELECT_AND | SELECT_SUB, point[0], point[0] );
work_sel = Select();
if( SelectPolygons() < 2 )
{
Warning();
if( MESSAGE == ON )
{
temp = PolyVertex( point[0] );
sels = SelectPolygons();
if( temp == point[0] )
{
if( sels == 0 )
Message( "選択面中にこの点は含まれていません" );
else if( sels == 1 )
Message( "選択面中にこの点を含む面は1面しかありません\n"
+"削除する辺を指定してください" );
}
else
Message( error_msg1 );
}
Select( sel );
return;
}
Select( sel );
PushMenu();
Status_org = Status_title;
MenuPosition( Menu( " 動作設定(&S)",
"合成中止 ESC", MenuQuit
), Menu_Title );
ClearStatus();
Status_title[0] = "【面合成中】";
DrawStatus();
quit_flag = FALSE;
cur = Cursor();
pick = cur;
input_flag = OFF;
while( TRUE )
{
if( draw_flag == ON )
DrawLine( point[0], cur );
key = WaitEvent();
if( key )
input_flag = ON;
if( ( ShiftStat() & 1 ) == 1 )
{
cur = Cursor();
TrimCursor(point[0], MouseWindow());
Cursor( cur );
}
else
cur = Cursor();
key = KeyCode();
if( input_flag | key == INPUT_KEY )
{
Select( work_sel );
SelectArea( TRUE, SELECT_AND | SELECT_SUB, cur, cur );
if( SelectPolygons() < 2 )
{
Warning();
if( MESSAGE == ON )
{
temp = PolyVertex( cur );
if( temp != cur )
Message( "削除する辺を指定してください\n"
+error_msg1 );
else
Message( "この辺は削除できません" );
}
Select( sel );
}
else
{
point[1] = cur;
break;
}
}
else if( key == ESC | key == BS | quit_flag == TRUE )
{
PopandClear( OVERWRITE );
Select( sel );
return;
}
else
temp = KeyProcess( key );
if( ((key!=0 ) & (key != INPUT_KEY)) | ( pick != Cursor()) )
{
draw_flag = ON;
DrawLine( point[0], pick );
}
else
draw_flag = OFF;
pick = Cursor();
input_flag = OFF;
}
Clear( OVERWRITE );
EdgeSelect( Edge( point[0], point[1]), TRUE, SELECT_AND );
if( SelectPolygons() != 2 )
{
Warning();
if( SelectPolygons() > 2 )
Message( "辺を共有している面が3面以上あるので合成できません。" );
else if( MESSAGE == ON )
{
Message( "この辺は隣接する面がないので削除できません" );
}
PopMenu();
Status_title = Status_org;
DrawStatus();
Select( sel );
return;
}
work_sel = Select();
PolyLoad(work_sel, 0);
ty1 = PolyType();
vers1 = PolyVertexs();
temp1 = PolyGetVertex( 0 );
for( i = 0; i<(vers1-1);i++)
{
temp2 = PolyGetVertex( i+1 );
if( temp1 == point[0] )
{
if( temp2 == point[1] )
{
flag1 = ON;
break;
}
}
else if( temp1 == point[1] )
{
if( temp2 == point[0] )
{
flag1 = OFF;
break;
}
}
temp1 = temp2;
}
if( i == vers1-1 )
{
if( temp1 == point[1] )
flag1 = OFF;
else
flag1 = ON;
PolyShiftVertex( vers1-1 );
}
else
PolyShiftVertex( i );
for( i = 0; i< vers1;i++ )
v[i] = PolyGetVertex( i );
PolyLoad(work_sel, 1);
ty2 = PolyType();
vers2 = PolyVertexs();
temp1 = PolyGetVertex( 0 );
if( temp1 == point[0] )
flag2 = OFF;
else
flag2 = ON;
for( i = 0; i<(vers2-1);i++ )
{
temp2 = PolyGetVertex( i+1 );
if( temp1 == point[0] )
{
if( temp2 == point[1] )
{
flag2 = ON;
break;
}
}
else if( temp1 == point[1] )
{
if( temp2 == point[0] )
{
flag2 = OFF;
break;
}
}
temp1 = temp2;
}
if(i == (vers2-1))
{
if( flag1 != flag2 )
{
for( i = 2; i< vers1; i++ )
PolySetVertex( v[i], vers2+i-2);
}
else
{
for( i = 2;i<vers1;i++ )
PolySetVertex( v[vers1-i+1], vers2+i-2);
}
PolyVertexs( vers1+vers2-2);
}
else
{
if( flag1 != flag2 )
{
for( j = 2; j<vers1;j++ )
PolyInsVertex( v[vers1-j+1], i+1 );
}
else
{
for( j = 2;j<vers1;j++ )
PolyInsVertex( v[j], i+1 );
}
}
while( TRUE )
{
j = PolyVertexs() -2 ;
for( i = 0; i< j;i++)
{
temp1 = PolyGetVertex( i );
temp2 = PolyGetVertex( i+2 );
if( temp1 == temp2 )
break;
}
if( i == j )
{
if( PolyGetVertex( 1 ) == PolyGetVertex( j+1 ) )
{
PolyDelVertex( 0 );
PolyDelVertex( 0 );
}
else
break;
}
else
{
PolyDelVertex( i );
PolyDelVertex( i );
}
}
PolyType( ty1 & ty2 );
Select( sel );
PolyAppend( TRUE );
PolyDelete( work_sel );
Update( CLEAR );
UpdateObject();
PopMenu();
Status_title = Status_org;
DrawStatus();
}
function MovePolygons()
{
CopyMovePolygons( OFF );
Update( CLEAR );
UpdateObject();
}
function CopyPolygons()
CopyMovePolygons( ON );
//
// 移動
//
function Move()
{
ClearStatus();
Status_title[0] = "【モード:平行移動】";
DrawStatus();
InputEvent( MovePolygons );
KeyEvent( MovePolygons, INPUT_KEY );
}
function private RotatePolygons()
_Rotate( OFF );
//
// 回転
//
function Rotate()
{
ClearStatus();
Status_title[0] = "【モード:回転】";
DrawStatus();
InputEvent( RotatePolygons );
KeyEvent( RotatePolygons, INPUT_KEY );
}
function private ScalePolygons()
_Scale( OFF );
//
// 拡大
//
function Scale()
{
ClearStatus();
Status_title[0] = "【モード:拡大縮小】";
DrawStatus();
InputEvent( ScalePolygons );
KeyEvent( ScalePolygons, INPUT_KEY );
}
//
// 削除
//
function Delete()
{
var sel;
if( SelectPolygons() != 0 )
{
if( MESSAGE == ON )
{
DlogOpen( "面削除", 1, "いいえ", " はい " );
DlogMessage( 0,"選択されている面を削除しますがよろしいですか" );
if( DlogWait() == 0 )
return;
}
if( prevnext_flag == TRUE )
{
sel = Select();
if( SelectPolygons(( sel & prevnext_sel )^sel) == 0 )
{
Select( prevnext_sel );
PolyDelete( sel );
prevnext_sel = Select();
SelectAll( FALSE );
if(SelectPolygons( prevnext_sel ) <= prevnext_selno )
prevnext_selno = 0;
}
else
{
PolyDelete();
prevnext_flag = FALSE;
}
}
else
PolyDelete();
Update( CLEAR );
pers_rotation_flag = FALSE;
UpdateObject();
}
else
{
Warning();
if( MESSAGE == ON )
Message( "面が選択されていないので、削除できません" );
}
}
//
// 複写
//
function Copy()
{
ClearStatus();
Status_title[0] = "【モード:複写】";
DrawStatus();
InputEvent( CopyPolygons );
KeyEvent( CopyPolygons, INPUT_KEY );
}
//
// グリッド複写
//
function GridCopy()
{
ClearStatus();
Status_title[0] = "【モード:グリッド複写】";
DrawStatus();
InputEvent( GridCopyPolygons );
KeyEvent( GridCopyPolygons, INPUT_KEY );
}
//
// 面の方向統一
//
function UnityPoly()
{
var sel1, sel2, temp_sel1, temp_sel2, old_sel, new_sel;
var i, j, temp1, temp2, pos[2], flag;
if( SelectPolygons() < 2 )
{
Warning();
if( MESSAGE == ON )
Message( "面の方向を揃えることができません" );
break;
}
sel1 = Select();
sel2 = sel1;
SelectAllFalse();
while( TRUE )
{
if( SelectPolygons(sel2) < 2 )
break;
SelectNumber( sel2, 0 );
old_sel = Select();
while( TRUE )
{
EdgeSelect( EdgeSelect(), TRUE, SELECT_UPDATE );
new_sel = Select()&sel1;
if( old_sel == new_sel )
break;
temp_sel1 = new_sel^old_sel;
temp1 = SelectPolygons( temp_sel1 );
//print( "\nnow go ", temp1, " " );
for( i = 0; i< temp1; i++ )
{
SelectNumber( temp_sel1, i );
temp2 = EdgeSelect();
//Update( CLEAR );
//print( i ," " );
Select( old_sel | Select());
EdgeSelect( temp2, TRUE, SELECT_AND );
if( SelectPolygons( Select() & temp_sel1 ) != 1 )
{
Warning();
break;
}
temp2 = EdgeSelect() & temp2;
temp2 = EdgeSelectCount( temp2, 2 );
if( Edges( temp2 ) != 1 )
{
EdgeGetVertex(temp2, 0, pos );
EdgeSelect(Edge(pos[0], pos[1]), TRUE, SELECT_AND );
}
else
{
EdgeGetVertex( temp2, 0, pos );
}
//print( pos[0], pos[1], "\n" );
temp_sel2 = Select();
Select( temp_sel2 & old_sel );
if( SelectPolygons() < 1 )
{
Warning();
Update(CLEAR);
break;
}
PolyLoad();
flag = 0;
for( j = 0; j< PolyVertexs(); j++ )
{
if( PolyGetVertex( j ) == pos[0] )
{
if( j == (PolyVertexs()-1))
{
flag = 1;
break;
}
else
{
if( PolyGetVertex( j+1 ) == pos[1] )
{
flag = 1;
break;
}
}
}
else if( PolyGetVertex( j ) == pos[1] )
{
if( j == (PolyVertexs() -1))
{
flag = 2;
break;
}
else
{
if( PolyGetVertex( j+1 ) == pos[0] )
{
flag = 2;
break;
}
}
}
}
//print( "flag=", flag, "\n" );
Select( temp_sel2 & temp_sel1 );
if( SelectPolygons() < 1 )
{
Warning();
break;
}
PolyLoad();
DrawCurrent( TRUE );
for( j = 0; j< PolyVertexs(); j++ )
{
if( PolyGetVertex( j ) == pos[0] )
{
if( j == (PolyVertexs()-1))
{
if( flag == 1 )
{
PolyInvVertex();
PolySave();
if( PolyType() & POLY_SHADE )
PolyShadeInv();
}
break;
}
else
{
if( PolyGetVertex( j+1 ) == pos[1] )
{
if( flag == 1 )
{
PolyInvVertex();
PolySave();
if( PolyType() & POLY_SHADE )
PolyShadeInv();
}
break;
}
}
}
else if( PolyGetVertex( j ) == pos[1] )
{
if( j == (PolyVertexs() -1))
{
if( flag == 2 )
{
PolyInvVertex();
PolySave();
if( PolyType() & POLY_SHADE )
PolyShadeInv();
}
break;
}
else
{
if( PolyGetVertex( j+1 ) == pos[0] )
{
if( flag == 2 )
{
PolyInvVertex();
PolySave();
if( PolyType() & POLY_SHADE )
PolyShadeInv();
}
break;
}
}
}
}
}
Select( new_sel );
old_sel = new_sel;
}
sel2 = sel2^old_sel;
}
Select( sel1 );
Update( CLEAR );
UpdateObject();
}
//
// 面の方向反転(法線方向も反転)
//
function InversePoly()
{
PolyShadeInv();
while( PolyLoad())
{
PolyInvVertex();
PolySave();
}
UpdatePers( CLEAR );
UpdateObject();
}
//
// 面分割
//
function Separate()
{
ClearStatus();
Status_title[0] = "【モード:面分割】";
DrawStatus();
InputEvent( SeparatePolygons );
KeyEvent( SeparatePolygons, INPUT_KEY );
}
//
// 面合成
//
function Joint()
{
ClearStatus();
Status_title[0] = "【モード:面合成】";
DrawStatus();
InputEvent( JointPolygons );
KeyEvent( JointPolygons, INPUT_KEY );
}
//
// 面自動分割
//
function Calipoly()
{
var msg[2], i, flag;
msg = { "凸多角形する", " 三角形にする " };
PushMenu();
MenuPosition( Menu( " 面自動分割中" ), Menu_Title );
DlogOpen( "面自動分割", 1 );
DlogSelect( 0, "分割方法", msg, 0 );
i = DlogWait();
if( i == TRUE )
{
flag = DlogAnswer( 0 );
if( SelectPolygons() == 0 )
{
Warning();
if( MESSAGE == ON )
Message( error_msg3 );
return;
}
else
{
ConvexConvert();
if( flag == 1 )
TriangleConvert();
}
Update( OVERWRITE );
UpdateObject();
}
PopMenu();
}
//
// 面切断
//
function Zante()
{
ClearStatus();
Status_title[0] = "【モード:面切断】";
DrawStatus();
InputEvent( _Zante );
KeyEvent( _Zante, INPUT_KEY );
}
//
// PolyIDの2つが一緒かどうか調べる
//
function private CheckPolygon( id1, id2 )
{
var vers1, temp, temp2, v[MAXVERTEX];
var i;
PolyLoad( id1 );
vers1 = PolyVertexs();
temp = 0;
/*
while( TRUE )
{
temp2 = PolyGetVertex( temp );
for( i = (temp+1); i< vers1; i++ )
{
if( temp2 == PolyGetVertex( i ) )
break;
}
}
*/
for( i = 0; i< vers1; i++ )
v[i] = PolyGetVertex( i );
PolyLoad( id2 );
if( vers1 != PolyVertexs() )
return FALSE;
for( i = 0; i< PolyVertexs(); i++ )
{
if( v[0] == PolyGetVertex( i ) )
break;
}
PolyShiftVertex( i );
if( v[1] == PolyGetVertex( 1 ))
{
for( i = 2; i< PolyVertexs(); i++ )
{
if( v[i] != PolyGetVertex( i ))
return FALSE;
}
return TRUE;
}
else if( v[1] == PolyGetVertex( PolyVertexs() - 1 ) )
{
PolyInvVertex();
PolyShiftVertex( PolyVertexs() -1 );
for( i = 0; i< PolyVertexs(); i++ )
{
if( v[i] != PolyGetVertex( i ))
return FALSE;
}
return TRUE;
}
else
return FALSE;
}
//
// 同一面の削除
//
function DeleteSamePolygons()
{
var i, j, polyid, temp, temp2, sel1, sels1, sel2;
var hashsize;
hashsize = atoi(Modelrc( "Stack" )) - StackPtr() - 20 - MAXVERTEX;
if( hashsize > SelectPolygons()*6 )
hashsize = SelectPolygons()*6;
if( hashsize < SelectPolygons()*2 )
{
Message( "処理すべき面が多すぎます。\n"+
"選択範囲を狭めて再度実行してください。" );
return FALSE;
}
else if( SelectPolygons() < 2 )
{
Message( "重複チェックする面を2面以上選んでください。" );
return FALSE;
}
var hash[hashsize];
//var debug1 = 0, debug2 = 0;
sels1 = SelectPolygons();
for( i = 0; i< hashsize; i++ )
hash[i] = 0;
sel1 = Select();
SelectAll( FALSE );
sel2 = Select();
Select( sel1 );
PolyLoadInit();
for( i = 0; i< sels1; i++ )
{
polyid = PolyLoad();
temp = vector( 0,0,0);
for( j = 0; j< PolyVertexs(); j++ )
temp += Position( PolyGetVertex(j));
temp2 = (0+vx(temp)*5+vy(temp)*7+vz(temp)*11) % hashsize;
if( temp2 < 0 )
temp2 += hashsize;
/*
if( hash[temp2] == 0 )
debug1++;
*/
while( TRUE )
{
if( hash[temp2] == 0 )
{
hash[temp2] = polyid;
break;
}
else
{
//debug2++;
if( CheckPolygon( hash[temp2], polyid ))
{
sel2 = sel2 | SelectCurrent();
break;
}
else
temp2 = ( temp2+1 ) % hashsize;
}
}
PolyLoad( polyid );
}
PolyDelete( sel2 );
UpdateObject();
Update( CLEAR, WIN_PERS );
//print( debug1, "\n" );
//print( debug2 ,"\n" );
}
//
// 面の二重化
//
function DuplicatePolygon()
{
var sel1, i, sel1s;
if( SelectPolygons() == 0 )
{
Message( "処理する面を選択してください。" );
return FALSE;
}
sel1 = Select();
sel1s = SelectPolygons();
PolyLoadInit();
for( i = 0; i< sel1s; i++ )
{
PolyLoad();
PolyInvVertex();
PolyAppend( TRUE );
}
Select( Select()^sel1 );
PolyShadeInv();
Update( OVERWRITE, WIN_PERS );
UpdateObject();
}