辺の表示・非表示
詳細図などを描いているときに、ある部材を途中でカットして表現したい時が多々あります。そのようなとき「頂点移動ツール」の「辺の表示/非表示」を使うのですが、図形属性が四角形だったり、グループ図形だったりすると、まず多角形に変換したり、グループ内に入ったりする操作が煩わしいです。四角形でも、グループ図形でも 1クリックで「辺の表示・非表示」を切り替えるツールがあったら便利だと思い、プラグインを作ってみました。
「辺の表示・非表示」のダウンロード
アイコン付のプラグインツールとして、フリーで公開します。Vectorworks 12.5 (Win 環境で確認、Mac は未確認)以上で動作します。
- 「辺の表示・非表示」・・・・・・ ha_SideVisibleHidden0-31.zip (フリーウェア)
インストーラーおよびレジストリの登録はありません。
解凍して出来る「辺の表示・非表示.vst」ファイルを、Vectorworksのプログラムフォルダ内にある"Plug-Ins"フォルダにコピーしてください。
登録方法は、Vectorworksのメニューよりツール>作業画面>設計...を選択し作業画面の設計を行ってください。ツールグループは「hyodoarch」です。
(既にVectorworksを起動している場合は、Vectorworksを再起動してください)
動作の流れ
- クリック座標直下の図形のハンドル(hh)を得る
- 操作図形がグループの場合は、グループに入る(ネスト対応)。
- 四角形又は多角形の場合は、曲線に変換する
- ハンドル図形(hh)を多角形化
- 多角形が閉じていない場合は閉じる
- 元の曲線の選択解除
- 多角形化を選択
- 多角形化を線分に分解
- クリック座標直下の線分にハンドル(hhLine)を移す
- ハンドルした線分(hhLine)の両端座標を取得(片方で良い)
- 線分に分解した図形を消去
- 操作対象の図形(hh)の頂点の数を調べる
- 線分(hhLine)の座標と一致する操作対象の図形(hh)の頂点座標をループで探す
- その座標の表示属性が True なら False に、False なら True に SetVertexVisibility でセット
- 元の図形がグループ図形だった場合は、グループを出る(ネスト対応)
実は、グループ図形を扱う場合、ForEachObjectInLayerを使う方が簡単です。ソースも3/4ほど短くなりました。ネストされたグループの場合、再帰が使えないかと思っているのですが、ForEach~はうまくいかないです。
{*******************************************************************************
SideVisibleHidden 辺の表示・非表示
Copyright 2010 兵藤善紀建築設計事務所
www.hyodo-arch.com
2010.07.10 Ver 0.31 グループを出るときにトップレベルではなく、
ネスト数にしないと、グループ内での編集に不都合が生じるので対処。
2010.07.03 Ver 0.30 グループに入る方がシンプルなコードになる
2010.06.20 Ver 0.20 グループのネストに対応。但し効果的な方法ではない
2010.06.12 Ver 0.14 最後の頂点インデックスの表示・非表示に対応
2010.06.12 Ver 0.13 グループが一段階対応
2010.06.11 Ver 0.12 グループ解除してからハンドルを得る方法を模索
2010.06.11 Ver 0.10 コーディング開始
*******************************************************************************}
PROCEDURE SideVisibleHidden;
{$ DEBUG}
VAR
ClickPT1 :Vector; {クリックした座標}
hh,hhNewObj,hhLine :Handle; {操作対象ハンドル}
Rect2Poly :Handle; {四角形と多角形を曲線に変換するときに使うハンドル}
Poly2Pgon :Handle; {曲線を多角形を曲線に変換するときに使うハンドル}
ShowOtherObjectsInGroup :Boolean; {環境設定>画面 の設定値}
NumOfInGroup :Longint; {グループのネスト数}
LP1,LP2,PolyP :Vector; {基準線の両端の座標、多角形の頂点座標}
hhVertexNum :Integer; {ハンドル図形の頂点数}
PolyVertexType :Integer; {頂点の種類 Get(Set)PolylineVertex で使用}
PolyArcRadius :Real; {円弧の半径 Get(Set)PolylineVertex で使用}
ii,kk :integer; {カウンタ}
ObjTypeMess :STRING; {ダイアログ用メッセージ}
BEGIN
{初期化}
hh:= nil;
NumOfInGroup:=0;
{クリック座標直下の図形のハンドルを得る}
GetPt(ClickPT1.x, ClickPT1.y);
hh:=PickObject(ClickPT1.x, ClickPT1.y);
{グループのネスト数カウンタの初期化}
kk:=0;
{環境設定>画面 の設定「グループ編集時に他の図形を表示」をTrueにする}
ShowOtherObjectsInGroup:=GetPref(14);
IF ShowOtherObjectsInGroup=False Then SetPref(14,True);
{選択図形がグループ(T=11)の場合は、グループに入る}
While (GetType(hh)=11) Do Begin
kk:=kk+1;
SetSelect(hh);
DoMenuTextByName('Group Navigation Chunk',1);
DSelectAll;
hh:=PickObject(ClickPT1.x, ClickPT1.y);
End;
NumOfInGroup:=kk; {グループのネスト数}
{ハンドル図形が四角形(T=3)多角形(T=5)の場合は、曲線に変換}
IF (GetType(hh)=3) OR (GetType(hh)=5) THEN
Begin
Rect2Poly:=MakePolyline(hh);
DelObject(hh);{この操作は必須}
hh:=Rect2Poly;
End;
{ハンドル図形が曲線(T=21)の場合、表示・非表示したい辺の両端の座標を得る}
IF (GetType(hh)=21) THEN
Begin
hhNewObj:=MakePolygon(hh); {ハンドルを多角形化}
If NOT IsPolyClosed(hhNewObj) Then SetPolyClosed(hhNewObj, True);{多角形が閉じていない場合は閉じる}
SetDSelect(hh); {元の曲線の選択解除}
SetSelect(hhNewObj); {多角形化図形を選択}
DoMenuTextByName('Convert to Lines',0); {多角形化図形を線分に分解}
hhLine:=PickObject(ClickPT1.x, ClickPT1.y); {ClickPT1下の線分にハンドルを移す}
GetSegPt1(hhLine, LP1.x, LP1.y); {LP1とLP2(未使用)の座標を取得}
{GetSegPt2(hhLine, LP2.x, LP2.y);}
SetSelect(hhNewObj);SetSelect(hhLine); {分解した線分を選択}
DoMenuTextByName('Clear',0); {選択した線分を消去}
End;
{曲線(T=21)の処理。頂点座標がLP1と一致するインデックスを探し、表示属性を反転
PolylineVertexのindexは 1~、VertexVisibilityの頂点indexは 0~、ということに注意}
IF GetType(hh)=21 THEN
Begin
hhVertexNum:=GetVertNum(hh);
For ii:=1 To hhVertexNum Do
begin
GetPolylineVertex(hh,ii,PolyP.x,PolyP.y,PolyVertexType,PolyArcRadius);
If ((PolyP.x=LP1.x) & (PolyP.y=LP1.y)) Then
SetVertexVisibility(hh,ii-1, NOT GetVertexVisibility(hh,ii-1));
end;
HMove(hh,10,10); {再描画させるために一度移動し、戻すハック}
HMove(hh,-10,-10);
End;
{グループ図形だった場合は、グループを出る}
IF NumOfInGroup>0 THEN For ii:=1 To NumOfInGroup Do DoMenuTextByName('Group Navigation Chunk',2);
{環境設定>画面 の設定「グループ編集時に他の図形を表示」を元の値に戻す}
IF ShowOtherObjectsInGroup=False Then SetPref(14,False);
END;{SideVisibleHidden}
RUN(SideVisibleHidden);