2019年3月29日金曜日

わかる人だけわかればいい

わかる人だけわかればいい。割と突き放した感じのプロジェクトが3つ

JwwDocIO プロジェクト
SxfDocIO プロジェクト
テストプログラム

圧縮ファイルの扱いはまだ実装していない。

2019/7/24 公開停止

2019年3月25日月曜日

DWGファイルの文字データの長さ

DWGファイルの文字データの長さの限界って知ってますか?

大昔は画層名などは 31バイトで、TEXT図形の文字長のサイズは 255バイトでした。
EXTNAMES システム変数というのがあって、これを 1 にすると、画層名などが 255バイトまで使えるようになりました。MTEXT図形の場合、文字長のサイズの制限はありませんが、図形データ1個の最大サイズという縛りが別にありました。
AutoCAD2007でユニコード対応になって、画層名などが255文字に拡張されました。


AutoCADが64ビット対応になって、図形データ1個の最大サイズが拡張されています。これで複雑な3Dオブジェクトも1個の図形データとしてDWGファイルの中に収めることができるようになりました。
文字長は今ではDWG/DXFファイルで最大何文字という縛りはありません。
実際、10000文字以上の文字データを持つ図形を作成することも可能です。

ただし、図形のプロパティ ドッキングウィンドウには文字データの入力バイト数に限りがあります。AutoCADでは990文字までしか入力できませんでした。

ObjectARX には、図形の文字データの取得に関して、AcString クラスで文字データを取得する関数、ACHAR の配列のコピーを返してくれる関数、図形内部の文字データへの const ポインタを返してくれる関数が存在します。
ユーザーが事前に文字のサイズを調べて、文字列をコピーするバッファを用意する必要はありません。ACHARの配列のコピーをもらった場合はacDelString() API で解放する必要があります。

2019年3月24日日曜日

SXFファイル形式(P21, SFC, P2Z, SFZ) について

SXFファイル形式は現在4つの拡張子のものが出回っている。

  • P21 (STEP AP 202) STEP 規格に基づいた正式な SXF ファイル。1個の図形を定義するのに、何行も使うし、英数字それも大文字ばかりの内容を見ると、昔懐かしい FORTRAN や COBOL のソースコードのようだ。
  • SFC (SXF Feature Comment) 1行1図形で書かれている。内容的には P21 ファイルと等価なものである。行番号が気になるが、図形名(パラメータ,...) の記述は、C言語のソースコードにも見える。
  • P2Z (P21 Zipped) P21ファイルと、P21ファイルと一緒に添付すべき画像データファイルや属性定義ファイル(拡張子 SAF)を ZIP ファイルとしてまとめたもの。SXFファイルの正式な仕様として定められている。Microsoft Office の docx ファイルのようなカタログファイルの類は含まれておらず、フラットにまとめるファイルを入れればよい。P2Z, P21, SAF ファイルのファイル名本体部分は同じ。
  • SFZ (SFC Zipped) P2ZファイルのSFC版だが、正式な仕様ではない。
SXFファイルを読み書きするライブラリ

SXFファイルを読み書きするライブラリとして、common_lib_AP202.dll と common_lib.dll ファイルが世の中に出回っている。このライブラリの中では、MFC を使用しているが、エクスポートされたAPIは、C 言語呼び出しのファイルになっている。図形データは型なしのポインタで渡される。また図形データは、シーケンシャルアクセスしかできない。

このライブラリを使うのにあたって、この辺はもうちょっと扱いやすくしたいと思った点はこんなところ。

  • Jww が CDocument 派生クラスで読み書きできるのだから、SXF ファイルも CDocument 派生クラスになってもいいんじゃないか。
  • P2ZやSFZファイルも同様に扱いたい。
  • Unicode や 64 ビルドはどうか。
  • 図形の構造体そのものは手を付けない。
common_lib_AP202.dll と common_lib.dll をラッピングする、MFC拡張ライブラリの SXF 読み書きライブラリがあったらいいな。

AP202なのに何故P21なのか(そこはP22では)、知ってる人がいたら教えてください_(..)_


Jw_cadのデータ形式

Jw_cad の配布元に公開されている Jw_cadのデータ形式 が一番の資料である。

ここから読み取れることは、

  • Jw_cad のファイルを MFC の CDocument クラスから派生した CJwwDocument クラスとして定義
  • Jw_cad の各図形は、MFC の CObject クラスから派生した CData クラスを図形共通クラスとして定義し、その派生クラスにする
  • 図形のコレクションクラスには CTypedPtrList テンプレートを使用している
この資料から、Jww ファイルを読み書きする CJwwDocument クラスを実際に書いた。
これを MFC拡張ライブラリとして用意した。
MBCS 文字符号集合を使用した、32ビットバージョンなら、これで大丈夫。

しかし、時代は、Unicode が優勢である。64ビットも当たり前に使われている時代である。MBCS, 32ビットが前提のコードを、UNICODE, 64ビットでビルドしたときに起きた不都合はこれだった。

  • 文字列の取り扱い。CString クラスの変数や配列に読み込んでいる。メンバー変数としては CString クラスのままがよいが、ファイルに出力するときは、CStringA クラスの変数に代入して、それを ストリームに出力するとよいことがわかった。
  • ブロック作成日時の取り扱い。CTime クラスが使われている。Jwwファイルの中では32ビットの日時データになっているので、32ビット値として受け取り/書き出ししたものを CTime の変数に入れるようにする。2038年まであと19年、ヨシ!

もうちょっと形にしてから公開しますので、しばらくお待ちください。

2019年3月23日土曜日

フォントコンパイラを作ってみて

CADKhanSetup.msi のダウンロード
FontCompiler プロジェクト

AutoCADのシェイプソースファイル(拡張子 SHP)をコンパイル済みシェイプファイル(拡張子 SHX)に変換したり、コンパイル済みシェイプファイルをシェイプソースファイルに逆変換するフォントコンパイラを作ってみた。

SHPをSHXに変換するにはAutoCADのCOMPILEコマンドを使えば可能、SHXをSHPに変換するには、AutoCAD Express Tools の DUMPSHX.EXE を使えば可能だが、LT じゃない AutoCAD が必要になる。

SHX/SHP ファイルにはいくつか種類があって、それぞれ Shape 1.0、Shape 1.1 、Unifont、Bigfont、拡張ビッグフォント と呼ばれている。

Bigfont と拡張ビッグフォントの SHX ファイルのインデックス部分は、8バイト=1レコードで コード、データ長、データアドレス が含まれているが、他のフォントと異なり、コードの昇順には並んでいない。

       | INDEX CODE SIZE ADDR
----------------------------------- 
0023 0 00000 23 995B
002B 1 085BF 36 4DD36
0033 2 088BF 84 104FF
003B 3 089BF 69 144B1
0043 4 08ABF 104 18581
004B 5 08BBF 173 1C676
0053 6 08CBF 124 20789
005B 7 08DBF 84 2443A
0063 8 08EBF 95 28202
006B 9 08FBF 102 2BF5F
0073 10 090BF 98 2FEC1
007B 11 091BF 77 33E32
0083 12 092BF 87 379FC
008B 13 093BF 101 3B745
0093 14 094BF 57 3F4C1
009B 15 095BF 89 42DE9
00A3 16 096BF 93 4713C
00AB 17 097BF 95 4B036
00B3 18 0854C 20 4F26C
00BB 19 00000 0 0000
00C3 20 00000 0 0000
00CB 21 00000 0 0000
00D3 22 00000 0 0000
00DB 23 00000 0 0000
00E3 24 00000 0 0000
-----------------------------------

最初のコード 0000 はよいが、次のコードは 000A ではなく、85BF, 88BF,... となっている。途中に 1レコード 全部 0 の謎のパディング レコードもある。
他のビッグフォントのSHXファイルも確認したが、ビッグフォントのインデックス部分の規則性はわからなかった。
他の Shape 1.0/1.1 や Unifont ではコードの昇順でならんでいるので、Bigfont もコードの昇順で出力してみたところ、一応 使えるようだったので、
「よくわからんが、まぁ動いているからヨシ」の精神で、公開してみた。
もしフォントへのアクセスを高速化したいために何かしたいのなら、固定長レコードがコードの昇順で並べて二分探索でいけるやろって思うんですがねえ。

2019/7/24 公開停止

2019年3月15日金曜日

CAD Khan ツールのインストール

2019/3/23 FontCompiler ツールを追加しました。

Windows Installer (MSI)ができました。
CADKhanSetup.msi のダウンロード

とりあえずソースコードを見せるようにしていますけど、誰もがソースコードからどうにかできる訳ではないですし、ソースコードからどうにかしたいとも思わないでしょうし。

CADKhanSetup プロジェクト


2019/7/24 公開中止

2019年3月13日水曜日

AutoCAD シェイプフォント

シェイプソースファイル(拡張子 SHP)
シェイプフォントファイル(拡張子 SHX)

COMPILE コマンド、SHPファイルをSHXに変換
STYLE コマンド、文字スタイルにフォント(SHXファイルかTrueTypeフォント)を割り当て
LOAD コマンド、シンボルライブラリとしてのシェイプフォントの読み込み
SHAPE コマンド、シンボルを図面に配置

DUMPSHX ツール、SHX ファイルを SHPファイルに変換
(AutoCAD のインストール時にオプションの Express Tools をチェックすると、このコマンドラインツールがインストールされる)

(重要) AutoCAD LT や AutoCAD互換CADには、COMPILEコマンドもDUMPSHXツールも存在しない。

フォーマット
SHPファイルについては AutoCAD カスタマイズリファレンスの「シェイプファイルとフォントファイルのコンパイル」以降に記述されている。

SHXフォントは以下のシグネチャから始まる。

AutoCAD-86 shapes 1.0  (128文字+ %%c %%d %%p )
AutoCAD-86 shapes 1.1  (256文字+ %%c %%d %%p )
AutoCAD-86 unifont 1.0  (UnicodeのBMPに限る)
AutoCAD-86 bigfont 1.0  (MBCSフォント用)

文字数  LSB2バイトでファイルに含まれる文字数
文字コード0 の情報
文字コード0x0A (LF) の情報
文字コード 0x20 (SP) の情報
 ...

データは文字コードの昇順に並んでいる。
文字の形状によってサイズがまちまちだがシーケンシャルにデータが入っている
文字コード 0 はフォントの見出し情報として、次のものが含まれる。
・フォントの簡単な説明、著作権表示など
・1つの文字データが 何×何 のマス目で表現されているか
・基準線より上が何マスで、下が何マスか
・縦書き可能かどうかの制御ビット
・(MBCSフォントのみ)2バイトコードになる範囲
(日本語の場合、0x8140 から2バイトコードが始まり、途中 0xA0から0xDF は半角カタカナがあり、0xE040から2バイトコードが再開される。そのため 02 81 9F E0 FC と記述される、範囲の個数、下限、上限)

文字1つ分の書式は次のようになっている
・文字コード 古いシェイプは1バイト、UNIFONTは2バイト、BIGFONTは1バイトと2バイトのコードが混在。
・サイズ この後の部分のバイト数が LSBの2バイトで格納されている
・シェイプ名 文字用フォントは NUL の1バイト。シンボル用フォントは最大31バイト+NULバイト。CHARで格納。
・形状記述コード 1バイトのニーモニックとパラメータの組み合わせで文字やシェイプの形状が記述される

上位4ビットが0の場合、次の意味になります。
0        シェイプの終了
1       ペンダウン 以下のコードは画面,用紙に出力される
2       ペンアップ 以下のコードは画面,用紙に出力されない
3,R    以降のペンの長さをRで割る
4,R    以降のペンの長さをRで掛ける
5       ペンの今の位置をスタックに保存(4回まで)
6       スタックに保存されたペンの位置を復元
7,C    サブシェイプとして文字コードCを再生
 コードのサイズはシェイプの種類によって1バイトまたは2バイト)
 拡張ビッグフォントは部首をサブシェイプとして定義しているため、コード、位置X,Y、尺度X,Y といったデータを持つ。
8,X,Y ペンの移動・描画
9,X,Y,...,0,0 ペンの連続移動・描画
A,R,SC  八分円弧の定義 (詳細はカスタマイズ リファレンスを参照)
B,        別の円弧の定義 (詳細はカスタマイズ リファレンスを参照)
C,        別の円弧の定義 (詳細はカスタマイズ リファレンスを参照)
D,        連続円弧の定義 (詳細はカスタマイズ リファレンスを参照)
E         次のコードは縦書きのみ実行
 普通はペンの移動(8)で、文字の再生位置を調整することで文字を縦書きにします。

上位4ビットが1からFの場合、1バイトで移動距離と進行方向を示します
上位4ビット 1~F   ペンの移動距離
下位4ビット 0~F   ペンの進行方向(0が右、4が上、8が左、Cが下など)

SHPファイルでは、ニーモニックとパラメータは10進または16進で記述されます。
16進で記述する場合、先行0が付加されます。
0,  10進数の0です
1,    10進数の1です
99,  10進数の99です
001, 16進数の1です
099, 16進数の99(10進数では153)です

8 ペンの移動や 9 ペンの連続移動では、XとYが組みの値であることを強調するためにカッコをつけることがありますが、データとしての意味はありません。
また、-128 から 127 の変位を指定できます。マイナスは付けますが、プラスは付けません。

ツール
FontCompiler プロジェクト

コマンドラインツールで
FontCompiler  入力ファイル 出力ファイル
入力ファイルはSHPまたはSHXファイルを指定する
出力ファイルはSHXまたはSHPファイルを指定する(入力の反対)
パスを指定すれば、別のフォルダに出力することも可能。

(今は暫定的に Unifont の SHP を SHX にするケースを実装している。)

AutoCAD スライドファイルとスライドライブラリ

スライドファイル(拡張子 .SLD)
スライドライブラリファイル(拡張子 .SLB)

AutoCAD関連コマンド・ツール

  • MSLIDE コマンドで作成
  • VSLIDE コマンドで画面に表示
  • SLIDELIB ツールでSLDファイルをSLBファイルにまとめる


ファイルフォーマット
http://www.martinreddy.net/gfx/2d/SLD.txt

ライブラリ
SlideImageReader クラス
C# ソースコードで、スライドファイルまたはスライドライブファイルを読み込み、指定したビットマップとして出力する。
SlideImageReader.cs

ツール
スライドファイルビューワ
SlideViewer プロジェクト

SlideImageReaderクラスを使ったサンプルプログラム。プログラムのリソースに埋め込んだスライドライブラリを表示するほか、フォームにスライドファイルまたはスライドライブラリをドラッグ&ドロップすると、その内容を表示する。

拡張スライドライブラリ
SlideLibEx プロジェクト
このコマンドラインツールは、あるフォルダにあるスライド ファイル(.SLD)をスライド ライブラリ ファイル(.SLB)に結合するだけでなく、スライド ライブラリ ファイルからスライド ファイルを抽出する機能も持っている。

使い方
SLIDELIBEX C スライドライブラリ ソースフォルダ
 ソースフォルダにあるすべてのスライド ファイルを、スライドライブリにまとめる。
SLIDELIBEX X スライドライブラリ ターゲットフォルダ
 スライドライブラリに含まれるスライドファイルを、ターゲットフォルダに出力する。


異尺度注釈図形にアタッチされている尺度を知る

 異尺度注釈図形が持っている尺度(文字列)を表示する ;;; ;;; LISTANNOSCALE.LSP ;;; (defun C:LISTANNOSCALE ( / el id f)   (setq f T)   ;異尺度注釈図形を選択   (if (setq el (entg...