フリーソフトダウンロードページを追加しました

GコードNCデータの確認と学習支援ソフト、バージョン2

GコードNCデータの確認と学習支援ソフト、バージョン2

前回公開したソフト、進化させました。
変更点の一番の目玉は、キャンパスのサイズ変更と、図形の拡大・縮小です。
この機能追加は、自分自身でもかなりC++Builder の勉強になりましたので
C++Builderでの図形描画方法なども記事にしてみようと思います。
簡単な図形描画のC++Builder のサンプルソースも添付します。
他は、レイアウト変更や、真円への対応。
G90・G91モードの表示。
データの読み込み速度が、少し早くなりました。
後は、気が付いた、不具合の対処などになります。

バージョン2での変更点

キャンパスサイズ変更

ウィンドウサイズを変更する事で、図形描画領域を変更できるようになりました。
エディタ領域も変更できます。

この機能の実現は、なかなかできませんでした。
イメージとしての拡大・縮小は簡単ですが、そうすると、図形が変形されてしまいます。
図形としての、拡大縮小の方法が見つかりませんでしたが
やっと見つけた、こちらサイトの記事が参考になりました。
インターネット様様ですねぇ~
詳細は後ほど覚書として、書き残しておきます。

拡大・縮小

マウスの「MouseWheel」イベントを利用して実現しました。
ただし、描画レスポンスが悪いため、データ量が多いとホイール操作への追従が即座に反映されません。
下段の「SetScale」横で、拡大率を入力したほうが速く描画できます。
「MouseWheel」イベントはC++Builderで は大元の「Form」しか、このイベントがありません。
図形を描くキャンパス上でのみマウスホイールに対応したい場合には、マウスの位置がキャンパス上がどうかの監視が必要になります。
この方法も、後ほど書いておこうと思います。

移動

「移動」は、マウスクリック位置をキャンパス中心に移動するような操作になります。
通常のCADのような、マウス右でのドラッグのような操作は実現できませんでした。

真円

始点・終点が同一の円弧補間指令の真円指令に対応しました。

ダウンロード

Vector へは、現在登録申請中です。
登録完了しましたら、お知らせします

登録されました、こちらからもダウンロードできます

C++BuilderでGコード図形化の方法

NCファイル読み込みの高速化

このソフトの全体の流れとしては、
・ドロップされた、NCファイルを読み込み
・一ブロックごとに、座標やGコードを分析し
・図形データへ変換
・Image Canvasで描画
の流れで、処理しています。
そんな事もあり、NCファイルは一度「TStringList」へ登録し、その「TStringList」から、一行ずつ、「TRichEdit」へ追加後
さらに「TStringList」から、一行ずつ、NCデータ分析処理を行っていました。

TStringList *list = new TStringList;
reditNcFile->Lines->Clear();
list->LoadFromFile(FilePath);
for(int i=0; i < list->Count; i++){
  reditNcFile->Lines->Add(list->Strings[i]);
}

「TRichEdit」への読み込みは、こんな感じです。
「TStringList」は便利なので、結構よく使います。
ところが、大きめのファイルを読み込んでみると、結構時間がかかります。
読込み後のNCデータの分析ルーチンは、私が書いたコードなので、ここが遅いのは私のレベルの問題でしょうがないとしても、「TRichEdit」への読み込み時点で結構時間がかかっていました。
いろいろ検索しても、前回の公開時には見つからず、このまま公開しましたが、なんの事はない、「TRichEdit」から直接ファイルを読み込めば、瞬時に読み込みは完了し、「TRichEdit」の「Lines」を「TStrings *」で参照するほうがはるかに高速なのに気が付きました。

reditNcFile->Lines->Clear();
reditNcFile->Lines->LoadFromFile(FilePath) ; //直接読込む
TStrings *list;
list = reditNcFile->Lines;

さらに、NCデータファイルから一行ずつ文字列として取り出す場合
TStringList の、Strings[i] で取り出していましたが、
C言語標準の、FILE * でfopen し、fgets で取り出したほうがデータによっては高速でした

私の環境では、1MBのデータで、前バージョンでは
読込み:56秒 + 図形分析:76秒 = 132秒でしたが
今回のバージョンでは、
読込みは瞬時に終了し分析完了まで、約77秒ぐらいでした。
さらに、データの最後をクリックして、全体表示させてみると
前バージョンでは、5分以上でしたが、今回バージョンでは、2秒程度でした。
図形表示に関しては、前回はNCの一ブロックずつ描画処理していましたが
今回からは、処理した図形データを保存しておいて、一気に描画するような仕様に変更したのでクリック描画はかなり高速になりました。
分析処理ももう少し速くしたいのですが、この部分の改善には最初からの見直が必要で、継ぎ足し継ぎ足しでかなり肥大化してしまっているので、今更難しいかなぁと思っているところです。

エディタや図形領域のリサイズ

「Form」に「Memo」や「Image」を配置する際、まず土台として「TPanel」コンポーネントでレイアウトし、その上にImageコンポーネントを配置するようにします。
土台の「TPanel」は、「Align」プロパティで、「alTop」「alLeft」「alClient」などに設定しておくと、ウィンドウのリサイズ時に追従していきます。

C++Builderに図形を描かせる

C++Builder には、TCanvasオブジェクトが用意されているので、これを使用すれば簡単に図形を描く事ができます。
TCanvasは、TFormやTImage などのプロパティとして用意されているので、まずは対象のオブジェクトを配置して、そこに描く事になります。
例えば、上でPanelを2個配置しましたが、TPanelにはCanvasプロパティはないので、その上にTImage を配置して、そこに図形を描いてみます。
Panel2の上に、Image1を配置して、「Align」プロパティを「alClient」に設定します。
その後、Form1のFormCreateイベントに、線を描く指令を追加すると起動した時に図形が描画されます。

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  Image1->Canvas->MoveTo(100,100);
  Image1->Canvas->LineTo(200,200);
  Image1->Canvas->AngleArc(200,200,60,10,300);
  Image1->Canvas->LineTo(300,300);
}

こんな感じで、簡単に図形を描くことができます。
ただし、Canvas の座標系は一般的な数学の座標系と方向が違いますので
NCデータの図形化のような、数学座標系で図形を描きたい場合には、数学座標をCanvas座標系への変換が必要になります。

Canvas 座標系

数学座標系

一般的にNC機械のXY平面の
座標系は数学座標系と同じなので
(最近では稀ですが違う機械も存在します)
NCデータを描画させる時には、NC座標からCanvas座標への変換が必要になります。
これ単純にY軸の符号を変換だけでなく、原点をキャンパスのどこへもっていくかなど、ちょっと面倒です。

図形のリサイズ

図形を描いた、ウィンドウをリサイズしてみます。

あれぇ~
Panelはリサイズに追従しているのに、Image1上の図形は追従しません。
「Align」プロパティも「alClient」に設定しているのに何でだろう?
ここで結構悩みました。
実は、TImage のStretchプロパティをtrue に設定すれば追従するようになります。

ところが、画像としての追従なので、形状が歪になったり、線の太さが変わってしまったり、図形としては成り立たなくなります。
じゃぁどうすればいいのか?
やっと見つけたのが、こちらのブログでした。
「Delphi言語」の記事だったので、なかなか検索できなかったのでしょう。
言語の構文は違いますが、クラス名やプロパティはC++Builder も大差ないので参考にさせていただきました。

TBitmap *ImageA = new TBitmap;
ImageA->Width = Panel2->Width;
ImageA->Height = Panel2->Height;
Image1->Picture->Bitmap = ImageA;
delete ImageA;

こんな感じで、Image1 の土台であるPanel2 の現状サイズを取得して
新規に生成した、ImageAのサイズを合わせ
そのImageAを、Image1->Picture->Bitmap へ代入する事で実現できました。

マウスホイールの利用

マウスホイールで拡大・縮小をさせたいと思います。
マウスホイールは、TForm のMouseWheelイベントでは処理できますが
図形キャンパスの、TImageにはこのイベントがありません。
したがって、図形キャンパス内での、マウスホイール動作を処理したい場合には
マウスがTImage内かどうかの判定をする必要があります。
コントロール内でマウスを移動させたか?は
TImageの、onMouseMoveイベントで処理できます。
コントロール外へ移動したか?は
onMouseLeaveイベントで処理できます。
これを利用して、グローバル変数でマウス位置の状態を記録しておいて
コントロール内でのマウスホイール操作の場合のみ、拡大・縮小処理を行いました。

C++Builderのサンプルソース添付

以上の機能を盛り込んだ、サンプルソースファイルを添付します
数学座標系指令をキャンパス座標系へ変換し、リサイズやマウスでの拡大・縮小ができます。

C++Builder のサンプルソースファイルは、左よりダウンロードできます

C++Builder は最高!

プログラミングに興味がある方で、とりあえず簡単にビジュアル的なプログラムを作成してみたいと思っている人にとっては、最適なツールだと思います。
少し複雑な処理をさせようと思うと、C++の知識は必要になってきますが、
ちょっとした計算をさせたい場合は、エクセルマクロ的な操作で実行ファイル「EXE」を作成できます。
DLLのいらない、ネイティブな実行ファイルが作成できるので、エクセルを立ち上げないと動作しないエクセルマクロよりも簡単に利用できます。
こんな素晴らしいツールが個人使用なら無料で使用できますから、プログラムに興味あるかたは是非体験してみてください。

C++Builderカテゴリの最新記事

%d人のブロガーが「いいね」をつけました。