AFsoft WebSite(エーエフソフト・ウェブサイト)
 

オペレーティング・システムについて

プログラミングについて
ホームページについて
キャドについて
電子カタログについて
書籍・雑誌
イベント
リンク集
CADを考える:図形描画(1)
「SXF仕様書」の「図面情報」・「図面構造」について読み終わりましたので、次は幾何/表記要素という事で、点マーカや線分などの各フィーチャを見るという事になりますが、そこまで行くとデータ定義/作成・編集と同時に図形描画も行いたくなります。ここでは少しそれについて考えてみます。
 
Delphi で比較的容易に画面描画を行う手法については以下のものがあります。
Windows GDIWindows95〜
Windows GDI+Windows98〜 Win98〜2000はgdiplus.dll要
Direct2DWindowsVista/7〜 Vistaはアップデート要 印刷不可
OpenGLこれは3D描画なので除外
※DirectXは Delphiで扱うのは多少難しいのでパス
 
GDIについては、CAD作ろ!コーナーでも書きました。GDI+については、OSSの方で落書きテストプログラムを作成しました。Direct2Dについては、Delphi2010コーナーで書きましたので、それぞれで補完するようなプログラムを作成しようかと思います。
画面描画については、WindowsVista/7の場合には Direct2Dを利用し、使えない場合には GDIを利用。但し、塗り潰し関連と画像描画については GDI+を利用する事とします。
印刷(プリンタへの描画)については、GDIを利用、但し、塗り潰し関連と画像描画については GDI+を利用する事とします。
 
GDIは標準のGraphicsユニット、Direct2Dは Delphi2010の標準のDirect2Dユニットでそのままコーディング出来ますが、GDI+は「GDI+による落書きテストプログラム」にて利用させてもらった、http://www.progdigy.com/ にて公開されている「gdiplus.zip」を必要とする事としますので、それをダウンロードして展開し、pasフォルダの中身を、テストプログラムの隣に「gdip」というフォルダを作成してその中に入れるものとします。
  C:\AFsoft\Delphi2010\cad
    ├─ 001
    ├─ 002
    ├─ 003
    ├─ ・・・・
    ├─ gdip
Delphi2010のメニュー「プロジェクト」→「オプション」で「Delphiコンパイラ」頁の「検索パス」に上記の「C:\AFsoft\Delphi2010\cad\gdip」を追加しておきます。
 
取り合えず、ボタンを押したらGDI+で線を描く、という風にするとして、フォームにボタンと PaintBoxを配置し、uses節に「GDIPAPI, GDIPOBJ」を追加し
procedure TForm1.Button9Click(Sender: TObject);
var
 gra : TGPGraphics;
 pen : TGPPen;
begin
 gra := TGPGraphics.Create(PaintBox1.Canvas.Handle);
 pen := TGPPen.Create(MakeColor(255, 0, 0, 255));
 gra.DrawLine(pen, 0, 0, 200, 100);
 pen.Free;
 gra.Free;
end;
のように記述して、保存・再構築を行います。すると、Delphi2010は
[DCC エラー] DirectDraw.pas(365): E2154 'IDirectDrawSurface' 型は終了処理が必要です - 構造体の可変部に置くことは許されません
のようなエラーを表示します。どうも
{$IFDEF COMPILER5_UP}
 PDirectDrawSurface = Pointer;
{$ELSE}
 PDirectDrawSurface = IDirectDrawSurface;
{$ENDIF}
の箇所がうまく判別していないようですので、取り合えず、下記のようにコメント化しておきます。
// {$IFDEF COMPILER5_UP}
 PDirectDrawSurface = Pointer;
// {$ELSE}
//  PDirectDrawSurface = IDirectDrawSurface;
// {$ENDIF}
保存・再構築を行うと、更に以下のようなエラーを表示します。
[DCC ヒント] GDIPAPI.pas(1843): H2365 オーバーライドメソッド TPathData.destroy は、上位の TObject.Destroy と大文字/小文字が一致する必要があります
[DCC 警告] GDIPOBJ.pas(148): W1010 'Equals' メソッドが基本型 'TObject' の仮想メソッドを隠しました
・・・
という訳なので、
type
 TPathData = packed class
  public
   Count : Integer;
   Points : PGPPointF;
   Types : PBYTE;
   constructor Create;
   destructor destroy; override;
 end;
     ↓
type
 TPathData = packed class
  public
   Count : Integer;
   Points : PGPPointF;
   Types : PBYTE;
   constructor Create;
   destructor Destroy; override;
 end;
 
TGPPrivateFontCollection = class(TGPFontCollection)
 public
  constructor Create; reintroduce;
  destructor Destroy; override;
  function AddFontFile(filename: WideString): TStatus;
  function AddMemoryFont(memory: Pointer; length: Integer): TStatus;
end;
 
TGPImage = class(TGdiplusBase)
 protected
  nativeImage: GpImage;
  ・・・
 public
  ・・・
  destructor Destroy; override;
  function Clone: TGPImage;
  ・・・
 
TGPGraphicsPath = class(TGdiplusBase)
 protected
  nativePath: GpPath;
  ・・・
 public
  ・・・
  destructor Destroy; override;
  function Clone: TGPGraphicsPath;
  ・・・
 
TGPGraphics = class(TGdiplusBase)
 protected
  ・・・
 public
  ・・・
  destructor Destroy; override;
  procedure Flush(intention: TFlushIntention = FlushIntentionFlush);
  ・・・
 
TGPRegion = class(TGdiplusBase)
 ・・・
 function Equals(region: TGPRegion; g: TGPGraphics): BOOL;
     ↓
TGPRegion = class(TGdiplusBase)
 ・・・
 function Equals(region:TGPRegion;g:TGPGraphics):BOOL;reintroduce;
 
TGPMatrix = class(TGdiplusBase)
 ・・・
 function Equals(matrix: TGPMatrix): BOOL;
     ↓
TGPMatrix = class(TGdiplusBase)
 ・・・
 function Equals(matrix: TGPMatrix): BOOL; reintroduce;
 
これで取り合えずエラーやヒント・警告は表示されなくなります。次にDirect2Dですが、まず uses節に「Direct2D, D2D1」を追加し、ボタンを配置してそれをクリックした時のイベントハンドラを下記のようにします。
// [Direct2D]
procedure TForm1.Button10Click(Sender: TObject);
var
 D2DCanvas : TDirect2DCanvas ;
begin
 if TDirect2DCanvas.Supported then begin
  try
   D2DCanvas := TDirect2DCanvas.Create(PaintBox1.Canvas, ClientRect);
   with D2DCanvas do begin
    BeginDraw;
    RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); // アンチエイリアス無し
    Pen.Color := clGreen;
    DrawLine(D2D1PointF(0,0),D2D1PointF(200,200));
    EndDraw;
   end;
   D2DCanvas.Free;
  except
   ;
  end;
 end;
end;
 
取り合えずは、ただ単に、線を描いてみるというテストです。Direct2Dでは、DrawLineの代わりに GDI同様の MoveTo、LineToも使用できます。今回はここまでにしておきます。
 
 
それでは簡単なテストプログラムです。実行型ファイルは、サイズが大きくなるので含めていません。ソースだけです。Delphi2010でコンパイル/再構築を行った後、Windows98〜2000で実行を行う場合は、gdiplus.dll が別途必要となります。それは今後も同様となります。
 
CAD装置(1)
CAD装置(2)
メディア
AutoCADの
DIESELマクロ
CSV
DXF
PCES
IGES
STEP
数学とCAD
CAD作ろ!
CADを考える
 ▲PREV
 ▼NEXT
M7
Jw_cad
 
お問い合わせ 
本サイトはリンクフリーです
リンクバナー
(C)Copyright 1999-2015 By AFsoft All Rights Reserved.