|
前頁の続きで、ハッチングについてです。
それではハッチング要素データ(既定義(外部定義))の登録・描画について考えていきます。
ハッチング要素データ(既定義(外部定義))は、SXF仕様書では以下のように記載されています。
構造化要素|ハッチング(既定義) |
※SXF Ver.3.1仕様書より |
パラメータ | 型 | 説明 | 範囲 |
Layer | Int | レイヤコード | |
name[257] | Char | ハッチング名 |
0<文字列長≦256
バイト |
out_id | Int | 外形の複合曲線のフィーチャコード | |
Number | Int | 中抜きの閉領域数 |
0≦数<int(32bits)
の最大値 |
in_id |
CArray
<int,
int> | 中抜きの複合曲線のフィーチャコード(配列) | |
備考
|
複合曲線定義のフィーチャーコードの値がどういうものなのか?という記述はありませんので不明ですが、ここでは既に、複合曲線定義データの中で、1から開始するID番号として指定する事にしていますので、その番号を指定する、という事にします。
ハッチングの輪郭線=複合曲線定義での線の色・線種・線幅は、複合曲線定義で指定されますのでそれを描画するようにします。ハッチング線分の色・線種・線幅については、「外部定義」ですので、ハッチング名から参照されるハッチング外部定義データを参照する、という事になるでしょう。それについては「ハッチング(ユーザ定義)」での指定方法が参考になると思いますので後述します。
データ構造は下記のようにします。データ登録・変更時にハッチング線(hln,hl)内容を更新するものとします。描画はこの内容を見て行うものとします。
UnitData.pas |
type
・・・
THatchLine = record // ハッチング線
Color : Integer ; // 色 (0:レイヤ色 1〜256)
Ltype : Integer ; // 線種 (0:レイヤ線種 1〜32)
line_width : Integer ; // 線幅 (0:レイヤ線幅 1〜16)
x1,y1 : double ; // 始点座標
x2,y2 : double ; // 終点座標
end;
TDataHatch1 = record // 構造化要素|ハッチング(既定義)
exf : Boolean ; // 存在フラグ(True:有り False:無し)
Layer : Integer ; // レイヤ(1〜256)
name : string ; // ハッチング名(最大256バイト)
out_id : Integer ; // 外形の複合曲線のフィーチャコード
Number : Integer ; // 中抜の閉領域数(0〜)
in_id : array of Integer; // 中抜の複合曲線のフィーチャコード
hln : integer ; // ハッチング線数
hl : array of THatchLine; // ハッチング線
end;
・・・ |
データ追加用の関数は
function AddDataHatch1(s,st:string;lay,oid,num:integer;
iid:array of integer) : Boolean ; |
のようにします。線分・折線等と同様、最初に「データ追加先の複合図形名/シンボル名 null:用紙へ追加」を指定するようにしています。これでハッチング(既定義)データの登録は取り合えず出来るようになります。この関数内部では、作業用変数として、ハッチング領域図形用の zHArN,zHAr、ハッチング線用の zHLnN,zHLn、を使用しますが、終了時にメモリ解放を行います。この関数から、ハッチング線の計算用手続き MakeHatch1() を呼び出しています。変数 zHLnN,zHLn はこの手続きとの受け渡し用として使っています。計算されたハッチング線は、内部の線分データの集まりとして登録します(hln、hl)。
この次は、ハッチング(既定義)データの描画ですが、既に算出されたデータ内のハッチング線(hln,hl)の描画、及び、複合曲線定義により定義される外郭線・中抜きの描画を行います。
UnitDataGraph.pas |
// ハッチング(既定義)の表示
procedure DisplayHatch1(lay,cf,col,oid,num,hln:integer;
iid:array of integer;hl:array of THatchLine;st:string;t:TMatrix);
var
i,j,co : integer ;
lx1,ly1,lx2,ly2 : double ;
begin
// ハッチング線の表示
for i:=0 to hln-1 do begin
MtxXY(lx1,ly1, hl[i].x1,hl[i].y1, t);
MtxXY(lx2,ly2, hl[i].x2,hl[i].y2, t);
co := hl[i].Color ; if (cf = 1) then co := col;
DisplayLine(lay,co,hl[i].Ltype,hl[i].line_width,
lx1,ly1,lx2,ly2);
end;
//
with CData do begin
// 一応チェック
j := CCrvIDCheck(oid); // ID番号が有効かどうかをチェック
if (j = -1) then exit ; // ID番号無効
for i:=0 to num-1 do begin
j := CCrvIDCheck(iid[i]); // ID番号が有効かどうかをチェック
if (j = -1) then exit ; // ID番号無効
end;
// ハッチング領域図形のセット
zHArN := 1 + num ;
SetLength(zHAr,zHArN);
CCrvDataToHAr(oid,1); // 複合曲線定義 oid → 外郭部
j := 2 ;
for i:=0 to num-1 do begin
CCrvDataToHAr(iid[i],j); // 複合曲線定義 iid → 中抜き
Inc(j);
end;
// 外郭線の表示
j := CCrvIDCheck(oid);
if (cDef[j].invisibility = 1) then begin
co := cDef[j].Color ; if (cf = 1) then co := col;
DisplayHArLines(0,lay,co,cDef[j].Ltype,cDef[j].line_width,t);
end;
// 中抜き線の表示
for i:=0 to num-1 do begin
j := CCrvIDCheck(iid[i]);
if (cDef[j].invisibility = 1) then begin
co := cDef[j].Color ; if (cf = 1) then co := col;
DisplayHArLines(i+1,lay,co,cDef[j].Ltype,cDef[j].line_width,t);
end;
end;
// メモリ解放
DataClearHAr ;
end;
end; |
変数 cf、col はシンボル定義の際のためのものです。ハッチングのレイヤはデータ内で登録しますが、ハッチング線の色・線種・線幅については、ハッチング(既定義)データの場合、外部からの指定=UnitData.pas内の手続き MakeHatch1にて指定、となります。また、外郭線・中抜き線の色・線種・線幅については、複合曲線定義にて指定する事になっています。また、シンボル図形配置の場合には、シンボル図形配置データ内のレイヤ指定・色コード指定があります。ハッチング(既定義)データにレイヤコードはあるのでそれについては従来通りの指定方法で可能なのですが、色コードはありませんので、正常に色を表現させるために、変数 cf、colで仲介するようにしています。
この手続き内でも複合曲線定義のID番号チェックや、ハッチング領域図形のセットを行って、外郭線・中抜き線の表示を行い、その変数のメモリ解放をしています。これについては、時間の掛かる計算等はありませんので、データとして登録するのではなく、再計算して描画するようにしています。その為、2度手間のようになりますが、登録の際と同様な処理が一部入っています。
外郭線・中抜き線の描画用の手続き DisplayHArLines を追加しています。これは、ハッチング領域図形の作業用変数 zHArN、zHAr を直接参照して連続線を描画するものです。変数 zHArN,zHArは複数の複合曲線定義の連続線を格納するようにしていますが、この手続きは、全てを描画するのではなく、そのうちの指定した1つの複合曲線だけを描画します。
UnitDataGraph.pas |
// ハッチング領域図形の表示
procedure DisplayHArLines(n,lay,col,ltp,wid:integer;t:TMatrix) ;
var
c,cc,l,w, i,j : integer ;
ww, d1, lx1,ly1,lx2,ly2: double ;
begin
DisplayLayCol2(lay,col,ltp,wid, c,cc,l,w,ww); // 色・線種・線幅
//
if (CData.zLtp[l-1].Segment = 0)
or(CData.zLtp[l-1].SpaceMax * mm_dot < 2.0)
or(CData.zLtp[l-1].SpaceMax * mm_dot < ww ) then begin
MtxXY(lx1,ly1, CData.zHAr[n].a[0].x,CData.zHAr[n].a[0].y, t);
for j:=1 to CData.zHAr[n].an-1 do begin
MtxXY(lx2,ly2, CData.zHAr[n].a[j].x,CData.zHAr[n].a[j].y, t);
DisplayLineSub1(lx1,ly1, lx2,ly2);
lx1 := lx2 ;
ly1 := ly2 ;
end;
end
else begin
i := 0 ;
d1:= 0.0 ;
MtxXY(lx1,ly1, CData.zHAr[n].a[0].x,CData.zHAr[n].a[0].y, t);
for j:=1 to CData.zHAr[n].an-1 do begin
MtxXY(lx2,ly2, CData.zHAr[n].a[j].x,CData.zHAr[n].a[j].y, t);
DisplayLineSub2(l,i,d1, lx1,ly1, lx2,ly2);
lx1 := lx2 ;
ly1 := ly2 ;
end;
end;
end; |
現在はまだ斜め45°のハッチング線でのテストしか実装していませんが、
Unit1.pas |
・・・
SetLength(lx,5);
SetLength(ly,5);
CData.AddCCurveDef(1,1,1,1,1); // 複合曲線定義 #1
lx[0] := 40; ly[0] := 40 ;
lx[1] := 140; ly[1] := 40 ;
lx[2] := 140; ly[2] := 140 ;
lx[3] := 40; ly[3] := 140 ;
lx[4] := 40; ly[4] := 40 ;
CData.AddCCrvDataLines(1,5,lx,ly); // 折線
CData.AddCCurveDef(2,2,2,1,1); // 複合曲線定義 #2
CData.AddCCrvDataArc(2,36,0, 90,130,8,0,180); // 円は円弧2つで形成
CData.AddCCrvDataArc(2,36,0, 90,130,8,180,0);
CData.AddCCurveDef(3,4,4,1,1); // 複合曲線定義 #3
lx[0] := 60; ly[0] := 60 ;
lx[1] := 90; ly[1] := 90 ;
lx[2] := 60; ly[2] := 120 ;
lx[3] := 60; ly[3] := 60 ;
CData.AddCCrvDataSpline(3,3,10,4,0,lx,ly); // スプライン曲線
CData.AddCCurveDef(4,5,5,1,1); // 複合曲線定義 #4
lx[0] := 120; ly[0] := 60 ;
lx[1] := 90; ly[1] := 90 ;
lx[2] := 120; ly[2] := 120 ;
lx[3] := 120; ly[3] := 60 ;
CData.AddCCrvDataSpline(4,3,10,4,0,lx,ly); // スプライン曲線
lx := nil;
ly := nil;
// ----- ハッチングテスト -----
CData.AddDataHatch1('' ,'TEST',1,1,3,[2,3,4]);
CData.AddDataHatch1('部分図A','TEST',1,1,3,[2,3,4]);
DisplayAllData ; // 全データ表示
・・・ |
というような感じでハッチングデータの登録をして描画をすると下記のような感じになります。ハッチング名は「TEST」としていますが、ここに色々な既定義の名前を指定することによって様々なハッチングを行えるように実装しますが、それはまた次回にて。
それでは、ここまでのテストプログラムです。実行ファイル、gdiplus.dll、gdipフォルダは入っていません。ソースのみです。
|
|
CAD装置(1)
CAD装置(2)
メディア
AutoCADの
DIESELマクロ
CSV
DXF
PCES
IGES
STEP
数学とCAD
CAD作ろ!
CADを考える
▲PREV
▼NEXT
M7
Jw_cad
|