前回公開したソフト、進化させました。
変更点の一番の目玉は、キャンパスのサイズ変更と、図形の拡大・縮小です。
この機能追加は、自分自身でもかなりC++Builder の勉強になりましたので
C++Builderでの図形描画方法なども記事にしてみようと思います。
簡単な図形描画のC++Builder のサンプルソースも添付します。
他は、レイアウト変更や、真円への対応。
G90・G91モードの表示。
データの読み込み速度が、少し早くなりました。
後は、気が付いた、不具合の対処などになります。
バージョン2での変更点
キャンパスサイズ変更
ウィンドウサイズを変更する事で、図形描画領域を変更できるようになりました。
エディタ領域も変更できます。
この機能の実現は、なかなかできませんでした。
イメージとしての拡大・縮小は簡単ですが、そうすると、図形が変形されてしまいます。
図形としての、拡大縮小の方法が見つかりませんでしたが
やっと見つけた、こちらサイトの記事が参考になりました。
インターネット様様ですねぇ~
詳細は後ほど覚書として、書き残しておきます。
拡大・縮小
マウスの「MouseWheel」イベントを利用して実現しました。
ただし、描画レスポンスが悪いため、データ量が多いとホイール操作への追従が即座に反映されません。
下段の「SetScale」横で、拡大率を入力したほうが速く描画できます。
「MouseWheel」イベントはC++Builderで は大元の「Form」しか、このイベントがありません。
図形を描くキャンパス上でのみマウスホイールに対応したい場合には、マウスの位置がキャンパス上がどうかの監視が必要になります。
この方法も、後ほど書いておこうと思います。
移動
「移動」は、マウスクリック位置をキャンパス中心に移動するような操作になります。
通常のCADのような、マウス右でのドラッグのような操作は実現できませんでした。
真円
始点・終点が同一の円弧補間指令の真円指令に対応しました。
ダウンロード
Vector へは、現在登録申請中です。。
登録完了しましたら、お知らせします
登録されました、こちらからもダウンロードできます
- こちらからダウンロードできます(Ver2.6)
- 始めて実行する時には、セキュリティのメッセージが出ると思います。
- 「詳細情報」から「実行」をクリックしてください。
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++の知識は必要になってきますが、
ちょっとした計算をさせたい場合は、エクセルマクロ的な操作で実行ファイル「EXE」を作成できます。
DLLのいらない、ネイティブな実行ファイルが作成できるので、エクセルを立ち上げないと動作しないエクセルマクロよりも簡単に利用できます。
こんな素晴らしいツールが個人使用なら無料で使用できますから、プログラムに興味あるかたは是非体験してみてください。
コメント
かずばんさん、おつかれさまです。
一気に良くなりましたね。すごいです。
ぼくはC++はまったくわからないのでチンプンカンプンですわ(笑)
起動時にファイル名を渡す、アイコンにドロップして起動するような処理は
難しいのでしょうか?
ファイラーで描画したいデータにカーソルを置き、登録してあるプログラムを起動!
という使い方をする事が多いのです(要望)
Help内
「・移動はマウスクリック位置がキャンバ中心へ配置」 —> キャンバス
ZENKYUさん
いつもコメントありがとうございます。
「起動時にファイル名を渡す」は、簡単にできると思います。
今日帰宅してから、やる気があったら(^^ゞ、やってみますね
ただ、「ファイラーで描画したいデータにカーソルを置き」と言うのは、よくわからないので
ここに変更実施のコメントが追加されたら、やってみてください。
かずばんさん、ども~
>「起動時にファイル名を渡す」は、簡単にできると思います。
そ、そんなに急がなくても(^_^;)お仕事優先でお願いします。
(ぼくはあいかわらず○○○○○○です。「ファイラーで描画したいデータにカーソルを置き」
うまく説明できていませんでしたね。
NcCheck TEST.NCD のようにコマンドラインでファイル名を
引数で渡して起動するイメージです。
ちなみに NC2DXF3D ではファイル名を受け取って変換待ちになりました。が…
変換実行ではWin8.1 32bit では正常に完了しましたが
Win10 64bit ではアドレス不正アクセスでエラーになりました。
こちらもおいおい検討をお願いできたらうれしいです。
P.S
PCが64bitになって使っていた JGAWK が動かなくなり GAWK に変更したんですが
それまで使っていたスクリプトがエラーになったり、エラーにならなくても
結果が違ってたりであたふたしています。
プログラム環境を新しくしないとだめだね~
ZENKYUさん。
NC2DXF3D も使ってもらってたんですね!
ありがとうございます。
でも、これは結構古いですからねぇ。
動かないかもしれませんね。
実は、今回のソフトも、次回にはZ軸には対応しないつもりですが
DXFへの変換機能も追加しようと思っていたところです。
気長によろしくです
ところで、ファイルの引数渡しには対応してみました。
晩酌後だったので、あまりチェックしていませんが
とりあえず、ソフトアイコンへのドロップは動作しました。
かずばんさん、ありがとうございます。
>ソフトアイコンへのドロップ
>ファイルの引数渡し
希望していた動作の確認ができました。
こんな事もお酒飲みながら出来てしまうのですね。
ファイル管理ソフト上でたとえばあるNCデータにカーソルを置いておき
エディタ1に渡して起動
他のエディタ2の方に特有な機能があるときはそちらに渡して起動とか
描画ソフトに渡してパスの確認
転送ソフトに渡して制御装置に送信
と、言うように一つのファルに対して複数のソフトを使うので
引数渡しが出来る事はすごくうれしいです。
「DXFへの変換機能」もなんか偶然のリアルタイムだったなあ。
ncコードを10年ぶり書いてみましたが
残念ながら動きませんでした
「リストのインデックスが範囲を超えてます」というエラー出てしまいます
G90G17G00
G00 Z10.
G01 Z0 F100
G1 X100.
Y-100.
X-100.
Y100.
X100.
Y0
X0
G00 Z100.
M30
もしかして%いるのかな
やっとVER2,6をインストールしてみました
今回は動きました
なんだったのだろう
私の環境が悪いのかもしれない
そこでG90G1X100.
Y-100.
とすると座標軸にじゃまされて
X100.の部分の描画が見えません
私だけでしょうか
乱造さん、ZENKYUです。
僕の環境でもいきなり
G90G1X100.
Y-100.
とすると確かにそうなりますね。
NCデータの内容によって描画スケールを自動計算していると思うので
移動指令より前に
G90G00X0Y0
のように開始点を指令しておくといいようです。
乱造さん、ZENKYUさん
触っていただいて、ありがとうございます。
乱造さんの誤動作の件は、データやエディタのカーソル位置などと、キャンパスクリックのタイミングによってはエラーが発生したので
Ver2.6で少し編集してみました。
今回の件は、ZENKYUさんほぼピンポン!です
エディタのカーソル位置と図形は合わせるようにしているのですが
下矢印キーと押した時と、エディタ上でのクリックの時とちょっと
思うように動いてくれません
具体的には、下矢印を押すとエディタ上ではかってに、カーソルが下がる感じで行と図形が合わなくなる症状が出てきました
しょうがないので無理やり合わせる処理をさせてます
それで、一行目を無視する動作になってしまっている感じです。
とりあえず、NCデータの一行目には、移動コマンドはこないだろう!
という、言い訳モード仕様です。(^^ゞ
今は、DXF変換機能を追加しているので、できそうだったら検討してみます。
ほぼ完成したので、近々公開しますのでよろしくです。
DXFは触りの知識しかありませんでしたので、もう少し掘り下げて勉強してみました。
いい暇つぶしになってます。
ZENKYUさん。
今もそうですが、飲みながらではないです。
もう飲んだ後です。でもいい気持ち・・・
昔は、こんな状態で、自作のPCいじくったりして、大変な事になったりしました(^^;
DXF変換は、確認した後、再度変換したDXFをCAD/CAMに読み込んで
使用輪郭と照合などで再確認したりしてます。
なので、そのうちに仕様には追加しようと思っていますので、よろしくお願いします。
乱造さん
検証ありがとうございます。
乱造さんのデータ、私も打ち込んでみましたが、とりあえず正常でした
コピペもしてみましたが、大丈夫でした。
ただ、
「リストのインデックスが範囲・・」のエラーは、開発中でもよくでたので
エディタのクリック位置とか、矢印キーのタイミングとか・・・
なにかのタイミング処理が悪いのだと思います
私も素面になってから、明日やってみますが
もし、なにかわかったら、お願いします
>「リストのインデックスが範囲・・」のエラー
データを読み込んでない状態で起動した時に
上矢印を押すと出ます。
下矢印では出ません。
出てもそこで「OK」を押してメッセージウィンドウをとじれば
続けて使えています。
% はあっても無くても変わりないようですね。
先日ある他のソフトでもあった現象なのですが
読み込んだNCデータと、「Edit」で編集した文字のうち
アルファベットだけがフォントサイズが変わるんですが
意図してそうしているんですか。それをどうこう言うわけではないですよ。
ありがとうございます。
そうか・・
何もない状態での、上矢印は処理していなかったです。
次回には検討したいと思います。
%の件は、あまり考慮していません。
とりあえず、基本的なGコードなら、ファナックでもOSPでもレダースでも
読み込めると思います
フォントサイズの件は、よくわかりません
私は、秀丸エディタを使用していますが、特にそんな症状なないです
>アルファベットだけがフォントサイズが変わるんですが
うまく説明できていなかったですね。
他のソフトというのは他のエディタという意味では無く
NcCheck での編集モードに入って編集した [A-Z] の文字のことです。
フォントの違いではないのかもしれませんが「幅」?「大きさ」?
が微妙に違います。数字の文字は変わらないように感じます。
もしかしてそれぞれのPC環境によって違ってくるのかな?
ちょっと再現はできませんでした。
今度、エディタの部分のFontも変更できないか検討しようと思っているのですがそれで何かわかるかな?
環境によって、字が小さくて見えない時があるので文字サイズぐらい変えられればいいかなと思ってます