|
これまで追加作図系の外部変形アプリケーションを作成してきましたが、今回は少し意趣を変えて、変更系の外部変形アプリケーションについて考えます。
変更系な外部変形アプリケーションの場合は
@変更したい要素データを選択
Aどういう風に変更したいのかを入力/指定
B読み込んだ要素データを削除
C変更した要素データを追加
で実現します。
注意しないといけないのは、変更しない無関係な要素データを読み取ってしまった場合、Bで削除してしまった後、Cで元情報で再度追加をせねばならない(これをしないと消してしまう事になる)という事です。
Bの削除については、
で可能です。またこれに関してバッチファイル指定
「REM #ht」 |
ブロック、曲線、寸法図形、ソリッドの消去と書出しをしない設定(読込みデータ「hd」選択データの削除への指示)
REM #ht1 ・・・ ブロックを消去しない
REM #ht10 ・・・ ブロックの消去と書き出しをしない
REM #ht2 ・・・ 曲線を消去しない
REM #ht20 ・・・ 曲線の消去と書き出しをしない
REM #ht3 ・・・ 寸法図形を消去しない
REM #ht30 ・・・ 寸法図形の消去と書き出しをしない
REM #ht4 ・・・ ソリッドを消去しない
REM #ht40 ・・・ ソリッドの消去と書き出しをしない |
があります。
それでは、ここでは線色変更の外部変形アプリケーションを作成してみることにします。まずはバッチファイルから。ブロックは無関係となりますので「REM #ht10」の指定を入れておきます。
|
p044_線色変更.bat |
REM p044−線色変更
@echo off
REM #jww
REM #cd
REM #hf
REM #zs
REM #zc
REM #zz
REM #zw
REM #h1
REM #hc 範囲選択をして下さい。
REM #ht10
REM #g1
REM #hr
start /w p044.exe |
|
プロジェクト「p044」の準備を行います。「C:\DelphiProgram\jww」フォルダの中に「p044」というフォルダを作成し、Delphi6を起動します。メニュー「プロジェクト」→「オプション」を実行し、下記の設定を行います。
[アプリケーション]頁
タイトル | p044−線色変更 |
[ディレクトリ/条件]頁
パス及びディレクトリ | C:\DelphiProgram\jww\p044 |
メニュー「ファイル」→「名前を付けて保存」
「C:\DelphiProgram\jww\p044」の中に「Unit1.pas」を保存
メニュー「ファイル」→「プロジェクトに名前を付けて保存」
「C:\DelphiProgram\jww\p044」の中に「p044.dpr」として保存
◆
Form1の画面は、取りあえずいつもと同じく、大きさを扱いやすいよう小さくし、オブジェクトインスペクタで Form1 のプロパティを設定します。
BorderIcons
biMaximize | False | 最大化しないように |
BorderStyle | bsSingle | 画面をリサイズしないように |
Caption | 線色変更 | タイトルバーに表示されます |
Color | clWhite | お好みでどうぞ |
Font内
Name | MS ゴシック |
プロポーショナルフォントは
文字配置調整が微妙なので |
Font内
Size | 10 | 小さいと少し見難い為 |
Scaled | False |
動作環境によっての文字の
大きさ変動を少し抑えられる |
メニュー「表示」→「プロジェクトマネージャ」
を実行し、コード画面の左側にドッキングさせておきます。前回作成した「MyFunc.pas」「JwwGaibu.pas」を取り込みます。分割点2・3で多少追加しましたが少し整理しておきます。特に、角度が「°」と「rad」が混在していますので、「°」の方は関数の先頭に「d」を付ける事にします。以前と関数名が異なりますので注意して下さい。
|
MyFunc.pas |
function Angle(dx,dy:double):double ;
function dAngle(dx,dy:double):double ;
procedure Rev(var rx,ry:double;x,y,cx,cy,a:double) ;
procedure dRev(var rx,ry:double;x,y,cx,cy,a:double) ;
procedure GetEllipsePt(var x,y:double;cx,cy,cr,he,ka,ang:double);
procedure dGetEllipsePt(var x,y:double;cx,cy,cr,he,ka,ang:double);
function GetEllipseAngle(x,y,cx,cy,cr,he,ka:double) : double ;
function dGetEllipseAngle(x,y,cx,cy,cr,he,ka:double) : double ; |
|
Unit1.pas の uses節に MyFunc と JwwGaibu を追加します。(※以下では全角空白を付けて桁調整等をしていますが実際は半角空白或いは無しです)
|
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,
MyFunc, JwwGaibu ;
type
TForm1 = class(TForm)
・・・ |
|
メニュー「ファイル」→「すべて保存」を行い
メニュー「プロジェクト」→「再構築」を行いエラー表示されない事を確認して下さい。
アイコンが Delphi6デフォルトのものになっていますので、メニュー「ツール」→「イメージエディタ」を実行し、そのメニュー「ファイル」→「新規作成」→「アイコンファイル」を実行し、16×16・16色のアイコンを作成します。(32×32でも構いませんし他のツールで作成するのでも構いません)「C:\DelphiProgram\jww\p044」の中に「Icon1.ico」として保存します。保存できたらイメージエディタを終了します。
メニュー「プロジェクト」→「オプション」を実行し、
[アプリケーション]頁の中の[アイコンの読み込み]ボタンをクリックし、「C:\DelphiProgram\jww\p044\Icon1.ico」を指定します。[OK]ボタンをクリックしてプロジェクトオプション画面を閉じます。
オブジェクトインスペクタにて、Form1 の Icon プロパティの入力欄右端の[…]をクリックして、[読み込み]ボタンをクリックし、「Icon1」を指定して、[OK]ボタンをクリックします。
◆
オブジェクトインスペクタにて Form1 の イベント OnShowの箇所でダブルクリック、OnCloseの箇所でダブルクリックし、取りあえず下記のように追記します。
|
Unit1.pas |
(・・・前略・・・)
type
TForm1 = class(TForm)
(・・・)
private
{ Private 宣言 }
AppPath : string ;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// 起動時
procedure TForm1.FormShow(Sender: TObject);
begin
Form1.Left := Mouse.CursorPos.X - Form1.Width div 2;
Form1.Top := Mouse.CursorPos.Y - 4;
// 初期設定
InitJwwGaibu ;
// プログラムのあるフォルダを取得します
AppPath := ExtractFilePath(Application.ExeName) ;
// JWC_TEMP.TXTを開きます
OpenTempFile(AppPath+'JWC_TEMP.TXT') ;
// 初期設定
S_Init ;
end;
// 終了時
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// JWC_TEMP.TXTを保存します
SaveTempFile(AppPath+'JWC_TEMP.TXT') ;
// 最終処理
EndJwwGaibu ;
end;
end. |
|
画面上に [Standard]内の Label を1つ配置し、Captionプロパティを「変更後の線色」とします。ComboBox コンポーネントを1つ配置します。オブジェクトインスペクタでプロパティを以下のように変更します。Styleプロパティが「csDropDownList」の場合は、ItemIndexプロパティで何個目を指定したのかを判断させます。ComboBox1の項目一覧はプログラム上で書くようにし、一番最初は「現在線色」とします。
|
ComboBox1
ImeMode | imDisable | 全角入力出来ないように |
Style | csDropDownList | キー入力せず項目選択のみ |
|
Button コンポーネントを2つ配置し、それぞれ以下のようにプロパティを指定します。
|
Button1
Caption | OK(&Y) | ボタン上の文字 |
Default | True | [Enter]キーを押したら[OK] |
Button2
Caption | キャンセル(&N) | ボタン上の文字 |
Cancel | True | [Esc]キーを押したら[キャンセル] |
|
画面のレイアウトは下図のようにしてみました。
Button1、Button2をダブルクリックして OnClickイベントを記述出来るようにします。取りあえず以下のように書いておきます。
|
Unit1.pas |
(・・・前略・・・)
// 起動時
procedure TForm1.FormShow(Sender: TObject);
var
i : integer ;
begin
(・・・)
// 初期設定
S_Init ;
ComboBox1.Items.Clear ;
ComboBox1.Items.Add('現在線色');
for i:=1 to 9 do
ComboBox1.Items.Add('線色'+IntToStr(i));
for i:=1 to 256 do
ComboBox1.Items.Add('SXF-'+IntToStr(i));
ComboBox1.ItemIndex := 0;
end;
// [OK]
procedure TForm1.Button1Click(Sender: TObject);
var
c : integer ;
begin
c := ComboBox1.ItemIndex ;
Close ;
end;
// [Cancel]
procedure TForm1.Button2Click(Sender: TObject);
begin
Close ;
end;
end. |
|
さて、これまでに、S_Col、S_Line、・・・のような関数・手続きは作成してきましたが、読み込んだ全てのデータ要素を書き出す、というような関数・手続きがありませんでしたので、それを作成してみます。
既に「分割点」を作成した際に、範囲選択した線分・円・弧楕円に対して処理を行う、というようなプログラムを作成しました。
|
// 線データ
for i:=0 to JW_EntLineN-1 do begin
with JW_EntLine[i] do begin
・・・・・
end;
end;
// 円データ
for i:=0 to JW_EntCircN-1 do begin
with JW_EntCirc[i] do begin
・・・・・
end;
end;
// 弧・楕円データ
for i:=0 to JW_EntArcN-1 do begin
with JW_EntArc[i] do begin
・・・・・
end;
end; |
|
というように、各要素データ数分、データ参照・各種処理の繰り返しを行うという事になります。上記の他、点、点マーカ、文字、寸法図形、ソリッド図形に対しても行います。ブロックについては、Jw_cadにその機能がありませんので無視します。
しかし上記のように記述してしまうと、要素データの順番が、線分→円→弧・楕円、となってしまいそうです。それを避けるため、データ読み取りの際に、要素順を動的変数 JW_EntNo(数は JW_EntN)へ格納するようにしています。これを利用して、
|
for j:=0 to JW_EntN-1 do begin
i := JW_EntNo[j].no ;
Case(JW_EntNo[j].yn) of
1: begin // 線データ
with JW_EntLine[i] do begin
・・・・・
end;
end;
2: begin // 円データ
with JW_EntCirc[i] do begin
・・・・・
end;
end;
3: begin // 弧・楕円データ
with JW_EntArc[i] do begin
・・・・・
end;
end;
・・・・
end; |
|
という具合に作成すれば、要素順はずれずそのまま出力する事が出来るであろうと想定されます。それでは記述してみます。文字列は任意サイズ文字となります。線分の場合には曲線属性も考慮します。次の要素が同じく線分で同じ曲線番号の場合はそのまま同じ曲線となりますが、それ以外の場合には、曲線属性ではなくなります。曲線属性の扱いは、Jw_cad 本来の機能と、外部変形での機能とは異なりますので注意して下さい。
|
Unit1.pas |
(・・・前略・・・)
// [OK]
procedure TForm1.Button1Click(Sender: TObject);
var
c,cn : integer ;
i,j,k : integer ;
f : Boolean ;
begin
c := ComboBox1.ItemIndex ;
cn:= 0 ;
SendMem('hd');
for j:=0 to JW_EntN-1 do begin
i := JW_EntNo[j].no ;
Case(JW_EntNo[j].yn) of
1:begin // 線データ
with JW_EntLine[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_Col(c,1);
S_Ltp(att.Ltp,0);
S_Wid(att.Wid);
if (CrvNo > 0) then begin
if (CrvNo <> cn) then begin
S_PLineStart ;
cn := CrvNo ;
end;
end;
S_Attr(att.Attr);
S_Line(x1,y1,x2,y2);
end;
// 次の要素が線分で同じ曲線属性かどうかをチェック
f := False ;
if ((j+1) <= (JW_EntN-1)) then begin
if (JW_EntNo[j+1].yn = 1)and(cn > 0) then begin
k := JW_EntNo[j+1].no ;
if (JW_EntLine[k].CrvNo = cn) then
f := True ;
end;
end;
if not(f) then begin
S_PLineEnd ;
cn := 0;
end;
end;
2:begin // 円データ
with JW_EntCirc[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_Col(c,1);
S_Ltp(att.Ltp,0);
S_Wid(att.Wid);
S_Attr(att.Attr);
S_Circle(cx,cy,cr);
end;
end;
3:begin // 弧・楕円データ
with JW_EntArc[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_Col(c,1);
S_Ltp(att.Ltp,0);
S_Wid(att.Wid);
S_Attr(att.Attr);
S_Arc(cx,cy,cr,sa,ea,he,ka);
end;
end;
4:begin // 文字データ
with JW_EntText[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_Mjs(0,mw,mh,md,c,1);
S_Mbs(cc);
S_Font(fo);
S_Attr(att.Attr);
S_Text(no,x1,y1,x2,y2,st);
end;
end;
5:begin // 点データ
with JW_EntPnt[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_PCol(c,1);
S_Attr(att.Attr);
S_Ten(px,py);
end;
end;
6:begin // 点マーカデータ
with JW_EntMark[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_PCol(c,1);
S_Wid(att.Wid);
S_Attr(att.Attr);
S_Mark(px,py,bai,ang,cod);
end;
end;
7:begin // 寸法図形データ
with JW_EntDim[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
with lin do begin
S_Col(c,1);
S_Ltp(att.Ltp,0);
S_Wid(att.Wid);
end;
with txt do begin
S_Mjs(0,mw,mh,md,c,1);
S_Mbs(cc);
S_Font(fo);
end;
S_Attr(att.Attr);
S_Dim(lin.x1,lin.y1,lin.x2,lin.y2, txt.x1,txt.y1,txt.x2,txt.y2, txt.st);
end;
end;
9:begin // 線形ソリッド図形データ
with JW_EntSld2[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_Col(c,1);
S_Wid(att.Wid);
S_Attr(att.Attr);
S_Solid2(x1,y1,x2,y2);
end;
end;
10:begin // 三角形ソリッド図形データ
with JW_EntSld3[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_Col(c,1);
S_Attr(att.Attr);
S_Solid3(x1,y1,x2,y2,x3,y3);
end;
end;
11:begin // 四角形ソリッド図形データ
with JW_EntSld4[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_Col(c,1);
S_Attr(att.Attr);
S_Solid4(x1,y1,x2,y2,x3,y3,x4,y4);
end;
end;
12:begin // 円ソリッド図形データ
with JW_EntSldC[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_Col(c,1);
S_Attr(att.Attr);
S_SolidC(cx,cy,cr,he,ka,sa,da,fl);
end;
end;
13:begin // 円周ソリッド図形データ
with JW_EntSldE[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_Col(c,1);
S_Wid(att.Wid);
S_Attr(att.Attr);
S_SolidD(cx,cy,cr,he,ka,sa,da,fl);
end;
end;
14:begin // 円環ソリッド1図形データ
with JW_EntSldO[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_Col(c,1);
S_Attr(att.Attr);
S_SolidO(cx,cy,cr,he,ka,sa,da,ri);
end;
end;
15:begin // 円環ソリッド2図形データ
with JW_EntSldG[i] do begin
S_LGrp(att.LGrp);
S_Lay(att.Lay);
S_Col(c,1);
S_Attr(att.Attr);
S_SolidG(cx,cy,cr,he,ka,sa,da,ri);
end;
end;
end;
Close ;
end;
(・・・後略・・・) |
|
メニュー「ファイル」→「すべて保存」を行い
メニュー「プロジェクト」→「再構築」を行いエラー表示されない事を確認して下さい。
Windowsのエクスプローラ等で、「C:\DelphiProgram\jww\p044」内に作成された「p044.exe」をフォルダ「Gapp」内へコピーします。外部変形を実行して動作確認をしてみて下さい。
− Additional −
要素データが多くなると「メモリ不足」と表示されたり、かなり遅くなってしまいますので、修正を行いました。遅くなる原因の1つは、動的配列を1データずつ増やしている事です。これを、1000データずつ増やすように変更しました(データは1個でも1000個分のメモリ確保を行います)。また、「JWC_TEMP.TXT」生成用メモリ JT_Mem の型を「String」から「ShortString」に変更しました。これに併せて文字データの方も ShortString にしてあります。ShortString は文字列の長さが255文字までとなりますが、そこまで長くなる事もほとんど無いであろうと想定しています。これにより「メモリ不足」メッセージ画面は出にくくなっています。
また、変換処理&生成用メモリ作成中、画面下部にカウンタを表示するようにしました。かなり多くの要素データの場合、止まったような状態となり、フリーズしたと勘違いする可能性があるためです。この際、[Esc]キーを押したかどうかをチェックして、押した場合には処理を中断するようにしてあります。実際に中断する場合には、[Esc]キーをしばらく押したままにして下さい(100個毎にカウンタ表示・[Esc]キーチェックを行っている為)。
今回のバッチファイルと実行ファイル、及び、ソースファイルについては、Pcataサイトに置いておきますので必要な方はそちらからダウンロードして下さい。
|
|
CAD装置(1)
CAD装置(2)
メディア
AutoCADの
DIESELマクロ
CSV
DXF
PCES
IGES
STEP
数学とCAD
CAD作ろ!
M7
Jw_cad
[BACK]
[NEXT]
|