【CADプログラミング】 STEP中間ファイル STEPCode Windows+cmake導入編
もともと、gccベースのSTEPCodeですが、LinuxだけでなくWindowsでも動作するように設計されています。今回はPython拡張ではなく、C++コードでの導入方法を見ていきましょう。
Linuxユーザやcmakeを頻繁に使う人には、割と良くある流れです。
ただし、現在のSTEPCodeはちょっと不便な点もあります。このあたりについては最後に触れます。
〇 開発環境
git
cmake-3.19.0-rc1 (今回はCMake GUIの結果を掲載します。CUI版はLinux編で触れます。)
Visual Studio 2019 (VC++拡張)
※試したことはないですが、最近のVC++はクロスプラットフォームへの拡張が進歩してきており、Visual Studio Codeでの実装も可能と考えています。
〇 インストール
(1) git cloneで、Windows OSのコアシステムが入っているドライブにソースコードをダウンロード。その後にbuildディレクトリを作成。
C:\>mkdir STEPCode
C:\>git clone https://github.com/stepcode/stepcode
C:\>cd STEPCode
C:\>mkdir build
(2) CMake Guiを開き、以下のように設定。
Where is the source code : C:\STEPCode
Where to build the binaries: C:\STEPCode\build
続いてConfigureボタンを押し、「Specify the generator for this project」を「Visual Studio 16 2019」にして実行。
しばらく待機すると、設定が完了します。
ここから先は、デフォルトであれば、そのまま進んでしまっても構いませんので、Generateボタンをクリックします。
成功したらGenerating doneと表示されます。
(4) buildフォルダに作成されたSCフォルダを開き、SC.slnを開きます。
ここで少し面倒なのですが、"Debug"を選択してまずビルドします。その後、C:\STEPcode\build\binにdllやexeが展開され、C:\STEPcode\build\libにlibが展開されますので、手動でDebugフォルダを作成して、そこにすべてのファイルのコピーを行います。
その後、"Release"に選択し、同じことを行い、手動でReleaseフォルダを作成して、そこにすべてのファイルのコピーを行います。
このステップは少し時間がかかりますので、最初にやってしまいましょう。ビルドがすべて終わると、こんな感じにフォルダに格納されます。
(5) 環境変数を手動設定してしまいましょう。スタートメニューの検索で「環境変数」を押して、「環境変数の編集」をクリックします。その次に現れた画面で「環境変数」をクリックして、以下のように環境変数をセットします。
STEPCODE_LIBを"C:\STEPCode\build\lib"に設定
STEPCODE_INCLUDEを
"C:\STEPCode\include"と"C:\STEPCode\build\include"に設定。
(環境変数を設定する場合は2つ設定します!)
STEPCODE_INCLUDE_BASEを"C:\STEPCode\src"と設定。
STEPCODE_INCLUDE_SCHEMAを"C:\STEPCode\build\schemas"に設定。
お気づきかと思いますが、参照するインクルードディレクトリ4つ、それとライブラリ、DLLという状況ですがDebugモードとReleaseモードで切り替えが必要、ということが分かります。
面倒であればDLL側のディレクトリを環境変数のPATHに設定することも可能ですが、(個人的に環境を汚すのはあまり好きではないので)プログラムを開発するたびに、exeファイルにdllのコピペを行うようにしています。
以上でインストール完了となります。
〇 プログラム(チュートリアル)
・プロジェクトは、C++コンソールプロジェクトで作成します。
以下、設定が少しややこしめなので注意してください。
・C/C++>一般>追加インクルートディレクトリの指定は、以下の指定にします。実をいうと、ソースコードのあるファイルを丸ごと突っ込んでいるだけなのですが、かなり長いです。なお、最後にあるsdai_ap214e3、というのは規格の名前ですので、入手した規格に従って入れてください。
$(STEPCODE_INCLUDE);$(STEPCODE_INCLUDE_SCHEMA)\sdai_ap214e3\;$(STEPCODE_INCLUDE_BASE)\base;$(STEPCODE_INCLUDE_BASE)\cldai;$(STEPCODE_INCLUDE_BASE)\cleditor;$(STEPCODE_INCLUDE_BASE)\cllazyfile;$(STEPCODE_INCLUDE_BASE)\clstepcore;$(STEPCODE_INCLUDE_BASE)\clutils
例えば、部品金具商社の最大手であるミスミ社のWebカタログのCADでは、AP203形式も展開されています。
その場合は、
$(STEPCODE_INCLUDE);$(STEPCODE_INCLUDE_SCHEMA)\sdai_ap203\;$(STEPCODE_INCLUDE_BASE)\base;$(STEPCODE_INCLUDE_BASE)\cldai;$(STEPCODE_INCLUDE_BASE)\cleditor;$(STEPCODE_INCLUDE_BASE)\cllazyfile;$(STEPCODE_INCLUDE_BASE)\clstepcore;$(STEPCODE_INCLUDE_BASE)\clutils
と指定します。
・ビルド条件は、いったんDebug, x64を指定します。
・追加ライブラリディレクトリを以下のように指定します。
$(STEPCODE_LIB)\$(ConfigurationName)
追加依存ライブラリの設定は以下のようにします。
base.lib;sdai_ap214e3.lib;stepcore.lib;stepdai.lib;stepeditor.lib;steplazyfile.lib;steputils.lib;%(AdditionalDependencies)
そして、ソースコード。簡単なものです。コードの解説は、次回以降に行いたいと思います。githubにあげるのは次回からにします。
ただし、return 0;で書かれている部分の一つ前
// STEPfile takes care of reading and writing Part 21 files
STEPfile* sfile = new STEPfile(*registry, *instance_list,
"D:\\DemoData\\Sprocket_2.stp", false);
は読み込むSTEPファイルになりますので、そこだけ適宜変更しましょう。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <STEPfile.h>
#include <sdai.h>
#include <Registry.h>
#include <SdaiHeaderSchema.h>
#include "schema.h"
int main()
{
// The registry contains information about types present in the current schema; SchemaInit is a function in the schema-specific SDAI library
Registry* registry = new Registry(SchemaInit);
// The InstMgr holds instances that have been created or that have been loaded from a file
InstMgr* instance_list = new InstMgr();
// Increment FileId so entities start at #1 instead of #0.
instance_list->NextFileId();
// STEPfile takes care of reading and writing Part 21 files
STEPfile* sfile = new STEPfile(*registry, *instance_list,
"D:\\DemoData\\Sprocket_2.stp", false);
return 0;
}
今回用意したSTEP中間ファイルは、PARTCommunityから適当に見積もりました。海外の方が作成したスプロケットを採用します。(色付きなので、AP214になっているようです)
〇 実行結果
実は、MISUMI-NOVAやPARTSolutionsで作成されたSTEPファイルを読み込むと、以上のような"Invalid instances"のエラーが2つほど発生するようです。これについては、現在発生原因をSTEPCodeのコミュニティに問合せしているところです。
なお、STEPファイルの構文(2行ほど)を変えれば直ります。今回の場合では、# 120, # 121にエラーがあるとのことですが、
# 120 = ( NAMED_UNIT( # 334 )PLANE_ANGLE_UNIT( )SI_UNIT( $, .RADIAN. ) );
# 121 = ( NAMED_UNIT( # 334 )SI_UNIT( $, .STERADIAN. )SOLID_ANGLE_UNIT( ) );
ここは主に単位系の定義をしている部分ですが、現状では機械部品を取り扱うことから非SI単位系であるmmが定義されているようなので、当面は無視でも大丈夫です。スケールが変わる場合はちょっと問題になりますが、本シリーズでは部品がメインなので支障はないでしょう。
# 120 = ( NAMED_UNIT( * )PLANE_ANGLE_UNIT( )SI_UNIT( $, .RADIAN. ) );
# 121 = ( NAMED_UNIT( * )SI_UNIT( $, .STERADIAN. )SOLID_ANGLE_UNIT( ) );
アスタリスクはNULLと同義です。これで、何とかなります。
〇 STEPCodeの問題点について
とまあ、結構ここまで手数を踏む必要があるSTEPCodeなのですが、その手数に実は問題があったりします。
・本来はWindows用にも、cmakeが対応できるようにフォルダ設定が必要なのですが、libフォルダ、binフォルダの設定がビルド条件ごとで変更できなくなっていて、Debugビルドを採用する場合はちょっと不便な思いをします。
・DLLも自動設定されないので、自分で環境設定PATHに登録するか、自分でコピペを繰り返す必要があります。
コミュニティ内でも、このあたりの課題は共有されている?かもしれませんが、詳しくは見れていません。元々はLinux用で使われるもので、ここから改良されるように動いていければと思います。
さらに、もう一つ致命的な問題があります。
AP203, AP214など規格が2種類以上あって、それを同じプログラム内で使用する場合は、ダイレクトに規格を変更できない
これは、先ほど指定しました環境変数のSTEPCODE_INCLUDE_SCHEMAのヘッダファイルschema.hに問題がありまして、よくみると
# ifndef SCHEMA_H
# define SCHEMA_H
~~~(いろいろな関数宣言)~~~
# endif
という形式となっています。つまり、全てschema.hが同名になっていて、ほかの規格を採用した場合に干渉することが発生します。
ちなみに、このことは実用上はあまり問題にならない気がします。なぜなら、その製造分野ごとで使用するSTEPファイルの規格が異なったものがやり取りされることが珍しいからです。
ですが、ソフトウエアを考えていく上では、この課題を避けては通れないケースもあるかと思いますので、本シリーズで気が向けば、「規格が衝突する場合にどのようなデータ構造をとれば実装できるか」も検討していきたいと思います。
(まあ、抽象クラスを使えば何とかなるのでは、というのが私の今の見解です)