nanoCAD 5.0 VB.NET + LISP サンプル
ncadNTED.dll for nanoCAD 5.0 2024/12/07 ~ 23, 29
・点在した TEXT をまとめて編集(選択順、または座標順)

・内部ブロックのイメージ表示、挿入 + 挿入後、交差する線分をカット

■ダイアログ表示のコマンド
□NTEDN : 選択順で TEXT を一括で編集します。TEXT の追加はできません。
空白行の TEXT は削除されます。
編集の行数が取得した TEXT 数を超えると、背景色が変わります。
取得した TEXT 数だけが、更新の対象になり、以降は無視されます。
□NTEDY : 座標順にソート後 TEXT を一括で編集します。
取得した TEXT が横方向に広がっているときは、X 座標の昇順、
縦方向に広がっているときは、Y座標の降順でソートします。
取得した TEXT の一番下側または、一番右側とその直前の TEXT の座標の
X 座標または Y 座標の差で、次の TEXT を作成します。
□BLKIN : 図面内のブロックのイメージ表示と挿入をします。
LINE, ARC, CIRCLE, LWPOLYLINE は白色で表示。
TEXT, MTEXTは緑色の四角形、ブロックは赤色の四角形+X印で表示。
ATTDEF、他の図形は表示されません
挿入は、原点 0,0 に挿入。COPYBASE 0,0 でコピー。PASTECLIP で挿入しています。
失敗した場合は、0,0 にブロックが残ります。
BlkInLsp.lsp がロードされているときは、挿入後ブロックに交差する線分をカットします。
■ncadnted.dll で追加されるその他のコマンド
□BLKJOIN
ブロックに交差する線分を結合
[Enter]で繰り返し可能
□BLKCUT
ブロックに交差する線分をカット
[Enter]で繰り返し可能
□LINEJOIN
選択した線分のうち、同一直線上の線分を結合
画層、線種、線色が違うときは、何もしない
[Enter]で繰り返し可能
■BlkInLsp.lsp で追加されるコマンド
いずれもブロック内の図形取得は、LINE, LWPOLYLINE, ARC, CIRCLE のみ
□BLKINLSP
DLL コマンド BLKIN から呼ばれる
[Enter] での繰り返しは不可(最後のコマンド "PASTE" が動く)
原点 0,0 にブロックを挿入、COPYBASE でコピー、ERASE で削除
PASTECLIP コマンドでコピー先を指示
ブロックに交差する線分をカット処理
ブロックに属性名 NAME, NAME1, SENBAN が含まれる場合は、属性値の入力。
次の PASTECLIP 先を指示
... を繰り返す
ESC で終了
□DWGRUN_BLOCKCUT
DwgRun.exe からブロック挿入後に呼ばれる
挿入されたブロックに交差する線分をカット処理
ブロックに属性名 NAME, NAME1, SENBAN が含まれる場合は、属性値の入力
[Enter] での繰り返しは不可
□BLINE
始点-終点の2点指示で、線分を作成
現在の画層が WIRE 画層のときは、電気配線作成(水平、垂直線分のみ、交点シンボル処理)
※交点シンボルは自動作成
上記以外は、通常の線分を作成(斜め線分も作成可能)
作成後、2点間にあるブロックの交差線分をカット
... を繰り返す
[Enter] での繰り返しは不可(最後のコマンド LINE コマンドが動く)
□BMOVE
ブロック、LINE、POLYLINEの1辺、TEXT を移動
ブロック:移動元のブロックの周囲の線分を結合。移動先でブロックに交差する線分をカット
ブロック名が、*KOUTEN*,*CMARK* にマッチするときはカットしない
LINE :線分上の1点を指示、
水平、垂直線分につながるブロック、LINE をストレッチコマンドで水平、垂直移動
線分の端点につながる POLYLINE の頂点も移動
移動対象ブロックにつながる線分は追従しない
POLYLINE:1辺上にあるブロックと周囲 2.5mm にある TEXT を一緒に移動
期待どおりにならないことがあるので注意!
TEXT :TEXT を移動、移動の基点は TEXT の基点
... を繰り返す
[Enter] での繰り返しは不可(最後のコマンド STRETCH コマンドが動く)
□BCUT
ブロック1個、または線分の1点を指示
ブロック:交差線分をカットカット
ブロック名が、*KOUTEN*,*CMARK* にマッチするときはカットしない
LINE :端点、または交点シンボルまでをカット、交点シンボルが不要であれば削除
... を繰り返す
[Enter] で繰り返し可能
□BCOPY
ブロック1個、または TEXT 1個をコピー
ブロック:コピー先で、ブロックに交差する線分をカット
ブロック名が、*KOUTEN*,*CMARK* にマッチするときはカットしない
ブロックに属性名 NAME, NAME1, SENBAN が含まれる場合は、
属性値の入力、数字が含まれる場合はカウントアップ
TEXT :TEXT をコピー、数字が含まれる場合はカウントアップ
[Enter] での繰り返しは不可(最後のコマンド PASTECLIP コマンドが動く)
□BERASE
削除するブロック1個、またはカットする線分の1点を指示
ブロック:削除後、周囲の線分を結合
LINE :端点、または交点シンボルまでをカット、交点シンボルが不要であれば削除
... を繰り返す
[Enter] で繰り返し可能
□BMARK
交点シンボルを反転
交点マークを消す座標、または追加する座標を指示
... を繰り返す
□BLPF
WIRE 画層の配線間隔を変更、配線上のブロックも追従
... を繰り返す
□BPT
複数のブロックの水平または垂直位置を合わせる
線番、交点シンボルは除外
... を繰り返す
以下、ブロック+普通の図形(LINE, LWPOLYLINE, ARC, CIRCLE)でもカットされる
ただし、部分削除の対象は、始点ー終点の間にある図形との交点のうち相互距離が最大な2点間で、
交点が1個のときは何もしない
いずれもブロック内の図形取得は、LINE, LWPOLYLINE, ARC, CIRCLE のみ
□XMOVE
複数の図形を移動
選択図形にブロックが含まれる時、左上(または右上)にあるブロックの挿入基点が移動基点になる
移動元の図形にかかる複数の線分を結合、移動先で交差する複数の線分を部分削除
... を繰り返す
ブロックと他の図形を一緒に移動するときは便利
□XCOPY
複数の図形をコピー
選択図形にブロックが含まれる時、左上(または右上)にあるブロックの挿入基点がコピーの基点になる
TEXT だけのときは、TEXT の基点がコピーの起点になる
コピー先で交差する線分を部分削除
... を繰り返す
ブロックと他の図形を一緒にコピーするときは便利
含まれる TEXT が1個で数字が含まれるときはカウントアップ可能
□XERASE
複数の図形を削除
図形にかかる複数の線分を結合
... を繰り返す
複数のブロックと他の図形を一括で削除するときに便利
□XCUT
複数図形に交差する線分を部分削除
選択した図形の矩形範囲を取得し、それに交差する線分が対象になる
その線分ごとに交差する選択した図形との交点のうち相互距離が最大な2点でカット
... を繰り返す
※線分の1点を指示しての部分削除はできない
□XLN
現在の画層に線分を作成
すでに線分がある時は、その線分の画層、線種、線色で作成、既存の線分と結合
始点ー終点の間にある図形(LINE, LWPOLYLINE, ARC, CIRCLE, INSERT)との交点のうち
相互距離が最大な2点間を部分削除
交点が1個のときは何もしない
... を繰り返す
□XSTR
選択した図形を水平、または垂直方向にストレッチ
STRETCH コマンドの C オプションと同じ
... を繰り返す
□XBREAK
選択した図形に交差する線分を部分削除
... を繰り返す
□TXGCLIP
LINE, POLYLINE で作成された表形式の文字列をクリップボードにコピー
1つの格子内に文字が複数ある場合は、印刷されない画層(DEFPOINTSとか)にダミーの区切り線が必要
JOGAI*, HOJO* にマッチする画層の線分は区切り線として採用しない
クリッ プボード経由で Excel との連携が可能
□TXGPASTE
クリップボードの文字列を LINE, POLYLINE で作成された部品リストに流し込み
JOGAI*, HOJO* にマッチする画層の線分は区切り線とし採用しない
表の縦横のマス目の数が違う場合は、合うところまで作成、変更される
まったく TEXT が存在しない場合は、現在の画層に指定した文字高さ、文字基点 ML で作成される
クリッ プボード経由で Excel との連携が可能
新規の部品リストの場合、項目のタイトルとデータの1行目に参照用のダミーデータを入れておくと、
文字高さ、文字幅、文字基点が参照される
まったく何も無い場合は、現在の画層に左中基点、指定の文字高さ、文字幅1.0 で作成される
□TXGG
LINE, POLYLINE で囲われた格子内の文字位置を一括で ML, MC, MR に変更
TEXT の基点から上下左右4方向に *LINE を検出しているため、表形式でなくても使用可能
□TXCLIP
選択した TEXT をクリップボードにコピー
□TXPASTE
クリップボードの文字列を指定した文字高さ、行間で TEXT として作成
列幅は全体の文字幅+αで作成
必要であれば、罫線を作成
□TXGSPC
LINE, POLYLINE で作成された格子の縦横の大きさを変更
部品リスト、端子配列図等の行間、列幅の変更に使用
□TXUP
TEXT カウントアップコピー(10進数のみ)
□TXPLS
複数 TEXT の数字部の一括加算、減算
□TXPLS2
複数 TEXT の数字部の一括加算、減算( -, +, ±対応版)
□TXRP
TEXT の置換
□TXFILL, LNFILL, ENTFILL
TXFILL:2つの TEXT を選択して、その相互間隔で指定方向に 10進、16進、8進カウントアップコピー
TEXT が1つのときは、コピー間隔を2点で指示または距離を入力
ENTFILL:2 以上の図形を選択して、並び方向と同じ方向であれば、最後の相互間隔で指定方向にコピー
選択図形 が1のときは、コピー間隔を2点で指示または距離を入力
並び方向と違う方向であれば、選択図形すべてを相互間隔で指定方向にコピー
ブロックの等間隔コピーにも使える
LNFILL:表の行、列の2本の LINE を選択して、その相互間隔で指定方向にストレッチ、コピー
LINE の等間隔コピーは、ENTFILL を使う
□LLDR
LINE の先端に片矢印(LWPOLYLINE)を作成
■一時的なロード
メニュー -「ツール」-「アプリケーション」-「.NET アプリケーションをロード...」で
ncadnted.dll を選択し、[ロード]ボタンをクリックするとロードされます。
LISP ファイルも同様です。
または、
メニュー -「ツール」-「アプリケーション」-「アプリケーションをロード...」で
ncadnted.dll を選択し、[ロード]ボタンをクリックするとロードされます。
LISP ファイルも同様です。
または、
コマンドラインに NETLOAD[Enter]でも DLL ファイルはロードできます。
■自動ロード
自動ロードするには、「スタートアップスイート」の下のカバンボタンをクリック。
[追加] ボタンをクリック。ncadnted.dll を選択して[開く] をクリックすると登録されます。
以降、ドキュメント開くごとに自動でロードされます。
LISP ファイルも同様です。
■高解像度環境での使用について
こちらの環境(高 DPI 環境)では、nanoCAD 自体と自前のフォームが小さくなる現象がありました。
nanoCAD のアイコン(または、nCad.exe) を右クリック。「プロパティ」をクリック。
「互換性」タブをクリック。[高DPIの設定] をクリック。
「高いDPIスケールの動作を上書きします。拡大縮小の実行元:」のチェックをオン。
その下のリストから「システム」を選択。[OK] をクリック。
で、こちらの環境では、正常に表示されるようになりました。
■参考ツール
連番作成、半角<->全角変換、置換 ... 等が必要なときは、TEXTEDIT.exe
他の CAD で作成されたブロックの挿入には、DwgRun.exe を試してみて下さい。
nanoCAD 日本語化、他のツール
http://izawa-web.com/nanocad/ncadtools.html
からダウンロードできます。
■免責事項、著作権
本ツールをダウンロード、ロード、使用したことによる事故、損害等の一切について、
作者 f.izawa はその責を負いません。
ご自身の責任でお使い下さい。
本ツールの著作権は、作者 f.izawa が所有し、これを主張します。
■関数カタログ
http://www.izawa-web.com/txt/BlkInLsp_CommandsList.txt
■ダウンロード
DLL の変更はありません。ncadElec.lsp の修正版を同梱しています。
http://www.izawa-web.com/zip/ncadnteddll_20241229.zip
最新版: BlkIn フォームに画層オン図形の描画チェックボックスを追加。
同梱 LISP に TEXT 置換 TXRP コマンドを追加。
http://www.izawa-web.com/zip/ncadnteddll_20241223.zip
最新版:DLL の変更はありません。
同梱 LISP に不要な文字が残っていたのを修正しました。
http://www.izawa-web.com/zip/ncadnteddll_20241222.zip
旧版:DLL の変更はありません。
http://www.izawa-web.com/zip/ncadnteddll_20241220.zip
旧版:
http://www.izawa-web.com/zip/ncadnteddll_20241219.zip
より izawa 仕様バージョン(LISP のエラー処理修正版):
http://www.izawa-web.com/zip/ncadnteddll_20241215b.zip
旧バージョン:
http://www.izawa-web.com/zip/ncadnteddll_20241215.zip
旧バージョン:
http://www.izawa-web.com/zip/ncadnteddll_20241214.zip
■参考ツール
連番作成、半角<->全角変換、置換 ... 等が必要なときは、TEXTEDIT.exe
他の CAD で作成されたブロックの挿入には、DwgRun.exe を試してみて下さい。
nanoCAD 日本語化、他のツール からダウンロードできます。
■履歴
2024/12/07 NTED 初版作成
2024/12/08 NTED フォームがリサイズされないのを手直し
2024/12/09 文字リストを削除しても TEXT が削除されないのを手直し
2024/12/11 BLKIN ブロックのイメージ表示、挿入を追加
2024/12/11a イメージ描画座標の計算に四捨五入を追加
2024/12/11b 属性を含むブロックを挿入した時、属性が作成されないため、
通常の -insert コマンドで挿入するに変更
2024/12/11c コマンドでの挿入を API での挿入に変更
ブロック、TEXT, MTEXT を四角形で表示を追加
微小円弧の描画でエラーになるのを対策
2024/12/12 LINE 描画で 片方の端点が 1 ピクセルずれるのを手直し
ブロックの矩形描画で X印の描画を追加
使用しない COM 参照が残っていたのを削除
2024/12/14 BLKIN に [INSERT + CUT] ボタンを追加
これに使用する LISP と関連するコマンドを追加
2024/12/15 LISP を変更
挿入後の属性値入力を追加
BCOPY を COPY コマンドから COPYBASE - PASTECLIP に変更
BCOPY の対象図形に TEXT を追加
BCOPY に TEXT、属性値 のカウントアップコピーを追加
2024/12/15a ブロック名が、*KOUTEN*,*CMARK* にマッチするときはカットしない
BMOVE の対象図形に、LINE, LWPOLYLINE を追加
2024/12/15b 同梱 LISP のエラー処理を修正
2024/12/16 BLINE で画層、線種、線色が違う線分を重ねて作成したとき、端点が変わってしまうのを修正
同梱 LISP をより電気仕様に変更
2024/12/19 LISP から DLL コマンドの呼び出しをとりやめ、不要なコマンドを削除
同梱 LISP を修正、コマンドを追加
2024/12/20 同梱 LISP にコマンドを追加
2024/12/21 同梱 LISP を修正、コマンドを追加
2024/12/22 同梱 LISP に不要な文字が残っていたのを修正
2024/12/23 BlkIn フォームに OnLayer チェックボックスを追加。
同梱 LISP に TXRP を追加
■作者連絡先
e-mail : f.izawa@dream.com
URL : http://www.izawa-web.com/
■ソースコード 2024/12/12
以下、最新ではありませんが、何かの参考になれば・・・。
'' Class1 ----------------------------------------
'' 2024/12/12
Imports Teigha.Runtime
Imports HostMgd.ApplicationServices
Imports Teigha.DatabaseServices
Imports Teigha.Geometry
Imports HostMgd.EditorInput
''
Imports System.Drawing
'' com
'Imports nanoCAD
'Imports OdaX
' alias
Imports _AcRx = Teigha.Runtime
Imports _AcAp = HostMgd.ApplicationServices
Imports _AcDb = Teigha.DatabaseServices
Imports _AcGe = Teigha.Geometry
Imports _AcEd = HostMgd.EditorInput
Imports _AcGi = Teigha.GraphicsInterface
Imports _AcClr = Teigha.Colors
Imports _AcWnd = HostMgd.Windows
Public Class Class1
'Declare Function FindWindow Lib "user32" Alias _
' "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As Integer) As Integer
Public Shared Function GetPolar(ByVal pPt As Point3d, ByVal dAng As Double, ByVal dDist As Double) As Point3d
Return New Point3d(pPt.X + dDist * Math.Cos(dAng), pPt.Y + dDist * Math.Sin(dAng), 0.0)
End Function
Public Shared Function GetPolar(ByVal pPt As Point2d, ByVal dAng As Double, ByVal dDist As Double) As Point2d
Return New Point2d(pPt.X + dDist * Math.Cos(dAng), pPt.Y + dDist * Math.Sin(dAng))
End Function
Public Shared Function GetAngle(p1 As Point2d, p2 As Point2d) As Double
Dim fuzz = 0.0000001
Dim dx, dy As Double
dx = p2.X - p1.X
dy = p2.Y - p1.Y
If Math.Abs(dx) >= fuzz And Math.Abs(dy) >= fuzz Then
Return Math.Atan2(dy, dx)
ElseIf Math.Abs(dx) < fuzz Then
If p2.Y > p1.Y Then
Return Math.PI * 0.5
Else
Return Math.PI * 1.5
End If
ElseIf Math.Abs(dy) < fuzz Then
If p2.X > p1.X Then
Return 0.0
Else
Return Math.PI
End If
End If
End Function
Public Shared Function GetAngle(p1 As Point3d, p2 As Point3d) As Double
Return GetAngle(New Point2d(p1.X, p1.Y), New Point2d(p2.X, p2.Y))
End Function
Public Shared Function GetDistance(p1 As Point3d, p2 As Point3d) As Double
Return Math.Sqrt((p2.X - p1.X) * (p2.X - p1.X) + (p2.Y - p1.Y) * (p2.Y - p1.Y))
End Function
Public Shared Function GetDistance(p1 As Point2d, p2 As Point2d) As Double
Return Math.Sqrt((p2.X - p1.X) * (p2.X - p1.X) + (p2.Y - p1.Y) * (p2.Y - p1.Y))
End Function
Public Shared Sub BulgeToArc(p1 As Point2d, p2 As Point2d, bulge As Double, ByRef p0 As Point2d,
ByRef rad As Double, ByRef st As Double, ByRef ed As Double)
Dim naikaku, d, hankei, kakudo1 As Double
' 膨らみから、ARCの中心の内角を求める
naikaku = Math.Atan(bulge) * 4.0
' ARCの始点-終点間の距離の1/2を求める
d = GetDistance(p1, p2) / 2.0
' 半径を求める
hankei = d / Math.Sin(naikaku / 2.0)
rad = Math.Abs(hankei)
' 中心座標を求める
kakudo1 = Math.PI / 2.0 - naikaku / 2.0
p0 = GetPolar(p1, kakudo1 + GetAngle(p1, p2), hankei)
' 膨らみの値により始点終点を入れ替える
If bulge < 0.0 Then
st = GetAngle(p0, p2)
ed = GetAngle(p0, p1)
Else
st = GetAngle(p0, p1)
ed = GetAngle(p0, p2)
End If
End Sub
'' 四捨五入
Public Shared Function RoundOff(d As Double, keta As Integer) As Double
Dim x As Double = 10 ^ keta
If d > 0 Then
Return Math.Floor(d * x + 0.5) / x
Else
Return Math.Floor(d * x + 0.5) / x
End If
End Function
'' データ保持用構造体
Structure TxtRecord
Dim index As Integer
Dim objId As ObjectId
Dim txtString As String
Dim txtPos As Point3d
End Structure
Public Shared TxtAry() As TxtRecord
Structure BlkRecord
Dim objId As ObjectId
Dim blkName As String
End Structure
Public Shared BlkAry() As BlkRecord
''ソート sortSw : 0=index 昇順, 1=X 昇順, 2=Y 降順
Public Shared Sub SortTxtAry(sortSw As Integer)
If TxtAry.Length > 1 Then
Dim temp As TxtRecord
For i = 0 To TxtAry.Length - 2
For j = i + 1 To TxtAry.Length - 1
If (sortSw = 0 And TxtAry(i).index > TxtAry(j).index) Or
(sortSw = 1 And TxtAry(i).txtPos.X > TxtAry(j).txtPos.X) Or
(sortSw = 2 And TxtAry(i).txtPos.Y < TxtAry(j).txtPos.Y) Then
temp = TxtAry(i)
TxtAry(i) = TxtAry(j)
TxtAry(j) = temp
End If
Next
Next
End If
End Sub
'' 最小、最大座標
Public Shared Sub RectTxtAry(ByRef minx As Double, ByRef miny As Double, ByRef maxx As Double, ByRef maxy As Double)
If TxtAry.Length > 0 Then
For i = 0 To TxtAry.Length - 1
With TxtAry(i).txtPos
If i = 0 Then
minx = .X
miny = .Y
maxx = .X
maxy = .Y
Else
minx = Math.Min(minx, .X)
miny = Math.Min(miny, .Y)
maxx = Math.Max(maxx, .X)
maxy = Math.Max(maxy, .Y)
End If
End With
Next
End If
End Sub
Public Shared Sub DispTxtAry(ByRef edform As Form1)
With edform
.TextBox1.Text = ""
For i = 0 To TxtAry.Length - 1
.TextBox1.Text += TxtAry(i).txtString
If i < TxtAry.Length - 1 Then
.TextBox1.Text += vbCrLf
End If
Next
.Label1.Text = "TEXT 数 = " & TxtAry.Length.ToString
.txtarycnt = TxtAry.Length
End With
End Sub
<CommandMethod("ntedn", CommandFlags.Modal)>
Public Shared Sub NtextEditN()
NtextEdit(False)
End Sub
<CommandMethod("ntedy", CommandFlags.Modal)>
Public Shared Sub NtextEditY()
NtextEdit(True)
End Sub
Public Shared Sub NtextEdit(sortFlag As Boolean)
Dim doc As _AcAp.Document = _AcAp.Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Using tr As Transaction = db.TransactionManager.StartTransaction
Try
'' 選択フィルター
Dim TypValAr(0) As TypedValue
TypValAr.SetValue(New TypedValue(DxfCode.Start, "TEXT"), 0)
Dim SelFtr As SelectionFilter = New SelectionFilter(TypValAr)
If sortFlag Then
ed.WriteMessage(vbLf & "座標順で一括編集する TEXT をガバっと選択して下さい.")
Else
ed.WriteMessage(vbLf & "選択順で一括編集する TEXT を順に選択して下さい.")
End If
'' 選択
Dim res As PromptSelectionResult = ed.GetSelection(SelFtr)
If (res.Status = PromptStatus.OK) Then
Dim SSet As _AcEd.SelectionSet = res.Value
If SSet.Count > 0 Then
Dim edForm As Form1 = New Form1()
If sortFlag Then
edForm.Text = "NTED-Y : TEXT 一括編集(座標順=追加可能)"
Else
edForm.Text = "NTED-N : TEXT 一括編集(選択順=追加不可)"
End If
'' データ格納
ReDim TxtAry(SSet.Count - 1)
Dim idx As Integer = 0
For Each SSObj As SelectedObject In SSet
If Not IsDBNull(SSObj) Then
Dim ssTxt As DBText = tr.GetObject(SSObj.ObjectId, OpenMode.ForRead)
If Not IsDBNull(ssTxt) Then
With TxtAry(idx)
.index = idx
.txtString = ssTxt.TextString
.objId = ssTxt.ObjectId
If ssTxt.Justify = AttachmentPoint.BaseLeft Then
.txtPos = ssTxt.Position
Else
.txtPos = ssTxt.AlignmentPoint
End If
End With
idx += 1
End If
End If
Next
If TxtAry.Length > 0 Then
Dim sw As Integer = 0
'' TEXT の並び方向
If TxtAry.Length > 1 Then
Dim minx, miny As Double
Dim maxx, maxy As Double
RectTxtAry(minx, miny, maxx, maxy)
Dim tateFlag As Boolean = (maxy - miny) > (maxx - minx) ''縦並び
If sortFlag Then
If tateFlag Then
sw = 2
Else
sw = 1
End If
End If
edForm.sortSw = sw '' TextBox の背景色の切り換え用
''ソート
If sw > 0 Then
SortTxtAry(sw)
End If
End If
'' Form に表示
DispTxtAry(edForm)
If _AcAp.Application.ShowModalDialog(edForm) = vbOK Then
Dim arr() As String = Split(edForm.TextBox1.Text, vbCrLf)
'' 修正
For i = 0 To arr.Length - 1
If i < TxtAry.Length Then
Dim objTxt As DBText = tr.GetObject(TxtAry(i).objId, OpenMode.ForWrite)
If arr(i) <> "" Then
If objTxt.TextString <> arr(i) Then objTxt.TextString = arr(i)
Else
objTxt.Erase() ''空白文字を削除
End If
Else
'' あとで追加
End If
Next
''削除 2024/12/08 追加
If TxtAry.Length > arr.Length Then
For i = arr.Length To TxtAry.Length - 1
Dim objTxt As DBText = tr.GetObject(TxtAry(i).objId, OpenMode.ForWrite)
objTxt.Erase()
Next
End If
''追加
Dim len As Integer = TxtAry.Length
If sw > 0 And len > 1 And arr.Length > len Then
Dim dx As Double = 0
Dim dy As Double = 0
If sw = 2 Then ''縦並び
dy = TxtAry(len - 1).txtPos.Y - TxtAry(len - 2).txtPos.Y
Else
dx = TxtAry(len - 1).txtPos.X - TxtAry(len - 2).txtPos.X
End If
Dim Bt As BlockTable = TryCast(tr.GetObject(db.BlockTableId, OpenMode.ForWrite), BlockTable)
Dim Btr As BlockTableRecord = TryCast(tr.GetObject(Bt("*Model_Space"), OpenMode.ForWrite), BlockTableRecord)
'' 最後の TEXT
Dim orgTxt As DBText = tr.GetObject(TxtAry(len - 1).objId, OpenMode.ForWrite)
Dim n As Integer = 1
'' 追加
For i = len To arr.Length - 1
Dim clonedTxt As DBText = TryCast(orgTxt.Clone(), DBText)
clonedTxt.TextString = arr(i)
If clonedTxt.Justify = AttachmentPoint.BaseLeft Then
clonedTxt.Position = New Point3d(clonedTxt.Position.X + dx * n, clonedTxt.Position.Y + dy * n, 0)
Else
clonedTxt.AlignmentPoint = New Point3d(clonedTxt.AlignmentPoint.X + dx * n, clonedTxt.AlignmentPoint.Y + dy * n, 0)
End If
Btr.AppendEntity(clonedTxt)
tr.AddNewlyCreatedDBObject(clonedTxt, True)
n += 1
Next
Bt.Dispose()
Btr.Dispose()
End If
'' 変更を反映
tr.Commit()
End If
'' フォーム破棄
edForm.Dispose()
End If
End If
End If
Catch ex As System.Exception
_AcAp.Application.ShowAlertDialog(ex.Message)
End Try
End Using
End Sub
Public Shared Sub SortBlkAry()
If BlkAry.Length > 1 Then
Dim temp As BlkRecord
For i = 0 To BlkAry.Length - 2
For j = i + 1 To BlkAry.Length - 1
If BlkAry(i).blkName.ToUpper() > BlkAry(j).blkName.ToUpper() Then
temp = BlkAry(i)
BlkAry(i) = BlkAry(j)
BlkAry(j) = temp
End If
Next
Next
End If
End Sub
<CommandMethod("blkin", CommandFlags.Modal)>
Public Shared Sub BlkIn()
Dim doc As _AcAp.Document = _AcAp.Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Using tr As Transaction = db.TransactionManager.StartTransaction
Try
Dim tbl As BlockTable = tr.GetObject(db.BlockTableId, OpenMode.ForRead, False)
Dim enu1 As IEnumerator = tbl.GetEnumerator()
Dim objId As ObjectId
Dim cnt As Integer = 0
While enu1.MoveNext()
objId = enu1.Current
Dim rec As BlockTableRecord = tr.GetObject(objId, OpenMode.ForRead, False)
Dim c As String = Left(rec.Name, 1)
If c <> "*" And c <> "_" And c <> "$" Then
'' ブロック名の列挙
''ed.WriteMessage(vbLf & rec.Name)
cnt += 1
ReDim Preserve BlkAry(cnt - 1)
With BlkAry(cnt - 1)
.objId = objId
.blkName = rec.Name
End With
End If
End While
If cnt > 0 Then
SortBlkAry()
Dim blkForm As Form2 = New Form2()
Dim i As Integer
For i = 0 To BlkAry.Length - 1
blkForm.ListBox1.Items.Add(BlkAry(i).blkName)
Next
If _AcAp.Application.ShowModalDialog(blkForm) = vbOK Then
Dim blkName As String = blkForm.TextBox1.Text
Dim index As Integer = blkForm.ListBox1.FindString(blkName)
Dim blkRecId As ObjectId
If BlkAry.Length > index Then
blkRecId = BlkAry(index).objId
If blkRecId <> ObjectId.Null Then
Using blkref As New BlockReference(New Point3d(0, 0, 0), blkRecId)
Dim curSpaceBlkTblRec As BlockTableRecord
curSpaceBlkTblRec = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)
curSpaceBlkTblRec.AppendEntity(blkref)
tr.AddNewlyCreatedDBObject(blkref, True)
'' 2024/12/11c
Dim blkdef As BlockTableRecord = tr.GetObject(tbl(blkName), OpenMode.ForWrite)
If blkdef.HasAttributeDefinitions Then
For Each oid As ObjectId In blkdef
Dim dbObj As DBObject = tr.GetObject(oid, OpenMode.ForRead)
If TypeOf (dbObj) Is AttributeDefinition Then
Dim acAtt As AttributeDefinition = dbObj
If Not acAtt.Constant Then
Using attref As AttributeReference = New AttributeReference()
attref.SetAttributeFromBlock(acAtt, blkref.BlockTransform)
attref.Position = acAtt.Position.TransformBy(blkref.BlockTransform)
attref.TextString = acAtt.TextString
blkref.AttributeCollection.AppendAttribute(attref)
tr.AddNewlyCreatedDBObject(attref, True)
End Using
End If
End If
Next
End If
tr.Commit()
doc.SendStringToExecute("copybase L " & vbCr & "0,0 ", True, False, False)
doc.SendStringToExecute("erase L " & vbCr, True, False, False)
doc.SendStringToExecute("pasteclip ", True, False, False)
'Dim ncadApp As Object = GetObject("", "nanoCAD.Application.5.0")
'Dim ncadDoc As Object = ncadApp.ActiveDocument
'ncadDoc.SendCommand("copybase L " & vbCr & "0,0 ")
'ncadDoc.SendCommand("erase L " & vbCr)
'ncadDoc.SendCommand("pasteclip ")
End Using
End If
End If
End If
blkForm.Dispose()
End If
Catch ex As Exception
_AcAp.Application.ShowAlertDialog(ex.Message)
End Try
End Using
End Sub
End Class
'' Form1 -------------------------------------------------------
'' nted 用
Imports Teigha.Runtime
Imports HostMgd.ApplicationServices
Imports Teigha.DatabaseServices
Imports Teigha.Geometry
Imports HostMgd.EditorInput
Public Class Form1
Public txtarycnt As Integer = 0
Public sortSw As Integer = 0
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Me.Hide()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'フォームのLoadイベントハンドラ
''Me.AutoSize = True
''Me.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
Me.AutoSize = False
Me.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly
'フォームの最大サイズを画面サイズにする
Me.MaximumSize = System.Windows.Forms.Screen.GetBounds(Me).Size
'Me.Width = System.Windows.Forms.Screen.GetBounds(Me).Width \ 2
'Me.Height = System.Windows.Forms.Screen.GetBounds(Me).Height \ 2
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
Dim len As Integer = TextBox1.Lines().Length
Label2.Text = "現在の行数 = " & len.ToString
'' TextBox の背景色を変更
With TextBox1
If sortSw = 0 And txtarycnt > 0 And len > txtarycnt Then
If .BackColor <> Drawing.Color.FromArgb(255, 255, 191) Then .BackColor = Drawing.Color.FromArgb(255, 255, 191)
ElseIf sortSw > 0 And txtarycnt > 0 And len > txtarycnt Then
If .BackColor <> Drawing.Color.FromArgb(191, 255, 255) Then .BackColor = Drawing.Color.FromArgb(191, 255, 255)
Else
If .BackColor <> Drawing.Color.White Then .BackColor = Drawing.Color.White
End If
End With
End Sub
Private Sub TextBox1_KeyDown(sender As Object, e As Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
If (e.Modifiers And Windows.Forms.Keys.Shift) = Windows.Forms.Keys.Shift Then
If e.KeyCode = 13 Then
'Me.Text = "Shift+Enter"
'Button1_Click(Button1, EventArgs.Empty)
End If
ElseIf e.KeyCode = 27 Then
Button2_Click(Button2, EventArgs.Empty)
End If
End Sub
End Class
'' Form2 -------------------------------------------------------
'' blkin 用
'' 2024/12/11c
Imports Teigha.Runtime
Imports HostMgd.ApplicationServices
Imports Teigha.DatabaseServices
Imports Teigha.Geometry
Imports HostMgd.EditorInput
'' for Form2
Imports System.Drawing
' alias
Imports _AcRx = Teigha.Runtime
Imports _AcAp = HostMgd.ApplicationServices
Imports _AcDb = Teigha.DatabaseServices
Imports _AcGe = Teigha.Geometry
Imports _AcEd = HostMgd.EditorInput
Imports _AcGi = Teigha.GraphicsInterface
Imports _AcClr = Teigha.Colors
Imports _AcWnd = HostMgd.Windows
Public Class Form2
Sub DrawLine(bmpW As Integer, bmpH As Integer, cenx As Double, ceny As Double, scale As Double, p1 As Point3d, p2 As Point3d, ByRef g As Graphics, apen As Pen)
Dim x1, y1, x2, y2 As Integer
x1 = Class1.RoundOff((p1.X - cenx) * scale + bmpW / 2, 0)
y1 = bmpH - Class1.RoundOff(((p1.Y - ceny) * scale + bmpH / 2), 0)
x2 = Class1.RoundOff((p2.X - cenx) * scale + bmpW / 2, 0)
y2 = bmpH - Class1.RoundOff(((p2.Y - ceny) * scale + bmpH / 2), 0)
g.DrawLine(apen, x1, y1, x2, y2)
End Sub
Sub DrawCircle(bmpW As Integer, bmpH As Integer, cenx As Double, ceny As Double, scale As Double, p0 As Point3d, rad As Double, ByRef g As Graphics, apen As Pen)
Dim x, y, d As Integer
x = Class1.RoundOff((p0.X - cenx) * scale + bmpW / 2, 0)
y = bmpH - Class1.RoundOff(((p0.Y - ceny) * scale + bmpH / 2), 0)
x = Class1.RoundOff(x - rad * scale, 0)
y = Class1.RoundOff(y - rad * scale, 0)
d = Class1.RoundOff(rad * scale * 2, 0)
If d > 0 Then '' 2024/12/11a
g.DrawEllipse(apen, x, y, d, d)
End If
End Sub
Sub DrawRect(bmpW As Integer, bmpH As Integer, cenx As Double, ceny As Double, scale As Double, p1 As Point3d, p2 As Point3d, ByRef g As Graphics, apen As Pen)
Dim x1, y1, x2, y2 As Integer
x1 = Class1.RoundOff((p1.X - cenx) * scale + bmpW / 2, 0)
y1 = bmpH - Class1.RoundOff(((p1.Y - ceny) * scale + bmpH / 2), 0)
x2 = Class1.RoundOff((p2.X - cenx) * scale + bmpW / 2, 0)
y2 = bmpH - Class1.RoundOff(((p2.Y - ceny) * scale + bmpH / 2), 0)
g.DrawRectangle(apen, x1, y2, x2 - x1, y1 - y2)
End Sub
Sub DrawArc(bmpW As Integer, bmpH As Integer, cenx As Double, ceny As Double, scale As Double, p0 As Point3d, rad As Double, stang As Double, edang As Double, ByRef g As Graphics, apen As Pen)
Dim x, y, d As Integer
x = Class1.RoundOff((p0.X - cenx) * scale + bmpW / 2, 0)
y = bmpH - Class1.RoundOff(((p0.Y - ceny) * scale + bmpH / 2), 0)
x = Class1.RoundOff(x - rad * scale, 0)
y = Class1.RoundOff(y - rad * scale, 0)
d = Class1.RoundOff(rad * scale * 2, 0)
Dim deg1, deg2 As Integer
deg1 = Class1.RoundOff(stang / Math.PI * 180.0, 0)
deg2 = Class1.RoundOff(edang / Math.PI * 180.0, 0)
If deg2 < deg1 Then
deg2 += 360
End If
Dim degsa As Integer = Math.Abs(deg2 - deg1)
If degsa > 0 And d > 0 Then ''2024/12/11a
g.DrawArc(apen, x, y, d, d, -deg1, -degsa)
End If
End Sub
Public Sub DrawBlockImage(ByVal blkObjId As ObjectId)
Dim doc As _AcAp.Document = _AcAp.Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Using tr As Transaction = db.TransactionManager.StartTransaction
Dim dxfName As String = ""
Try
Dim rec As BlockTableRecord = tr.GetObject(blkObjId, OpenMode.ForRead)
'' ブロック名の列挙
''ed.WriteMessage(vbLf & rec.Name)
'' 描画範囲
Dim minx, miny, maxx, maxy As Double
'' 描画対象の図形を保持
Dim objids As ObjectIdCollection = New ObjectIdCollection
Dim ent As Entity
Dim cnt As Integer = 0
Dim entcnt As Integer = 0
Dim txtcnt As Integer = 0
Dim mtxtcnt As Integer = 0
Dim attcnt As Integer = 0
Dim blkcnt As Integer = 0
For Each id As ObjectId In rec
entcnt += 1
ent = tr.GetObject(id, OpenMode.ForRead)
dxfName = ent.GetRXClass().DxfName
If dxfName = "LINE" Or dxfName = "ARC" Or dxfName = "CIRCLE" Or dxfName = "LWPOLYLINE" Or dxfName = "INSERT" Then
objids.Add(id)
Dim ext As Extents3d = ent.Bounds
If cnt = 0 Then
minx = ext.MinPoint.X
miny = ext.MinPoint.Y
maxx = ext.MaxPoint.X
maxy = ext.MaxPoint.Y
Else
minx = Math.Min(minx, ext.MinPoint.X)
miny = Math.Min(miny, ext.MinPoint.Y)
maxx = Math.Max(maxx, ext.MaxPoint.X)
maxy = Math.Max(maxy, ext.MaxPoint.Y)
End If
cnt += 1
ElseIf dxfName = "TEXT" Then
objids.Add(id)
txtcnt += 1
ElseIf dxfName = "MTEXT" Then
objids.Add(id)
mtxtcnt += 1
ElseIf dxfName = "ATTDEF" Then
attcnt += 1
Else
''ed.WriteMessage(vbLf & dxfName)
End If
If dxfName = "INSERT" Then
blkcnt += 1
End If
Next
Label2.Text = ""
Label3.Text = ""
Label4.Text = "TEXT = " & txtcnt.ToString
Label5.Text = "MTEXT = " & mtxtcnt.ToString
Label6.Text = "ATTDEF = " & attcnt.ToString
If attcnt > 0 Then
Label6.ForeColor = Color.Red
Else
Label6.ForeColor = Color.Black
End If
Label7.Text = "INSERT = " & blkcnt.ToString
Label1.Text = "図形数 = " & entcnt.ToString
''usesInsertCmd = attcnt > 0 '' 2024/12/11a
Dim bmpW As Integer = PictureBox1.Width
Dim bmpH As Integer = PictureBox1.Height
Dim img As New Bitmap(bmpW, bmpH)
Dim g As Graphics = Graphics.FromImage(img)
g.FillRectangle(Brushes.Black, g.VisibleClipBounds)
Try
If cnt > 0 Then
'' 描画範囲
Label3.Text = (maxx - minx).ToString("F1") & " x " & (maxy - miny).ToString("F1")
'' 描画
Dim dx As Double = maxx - minx
Dim dy As Double = maxy - miny
Dim cenx As Double = (maxx + minx) / 2
Dim ceny As Double = (maxy + miny) / 2
Dim scale As Double
If dx > dy Then
scale = bmpW / dx
Else
scale = bmpH / dy
End If
scale *= 0.85
For Each objid As ObjectId In objids
ent = tr.GetObject(objid, OpenMode.ForRead)
dxfName = ent.GetRXClass().DxfName
If dxfName = "LINE" Then
Dim ln As Line = TryCast(ent, Line)
DrawLine(bmpW, bmpH, cenx, ceny, scale, ln.StartPoint, ln.EndPoint, g, Pens.White)
ElseIf dxfName = "CIRCLE" Then
Dim cir As Circle = TryCast(ent, Circle)
DrawCircle(bmpW, bmpH, cenx, ceny, scale, cir.Center, cir.Radius, g, Pens.White)
ElseIf dxfName = "ARC" Then
Dim arcEnt As Arc = TryCast(ent, Arc)
DrawArc(bmpW, bmpH, cenx, ceny, scale, arcEnt.Center, arcEnt.Radius, arcEnt.StartAngle, arcEnt.EndAngle, g, Pens.White)
ElseIf dxfName = "LWPOLYLINE" Then
Dim pl As Polyline = TryCast(ent, Polyline)
Dim pt1, pt2, pt0 As Point2d
Dim bul1, bul2, rad, stang, edang As Double
For i As Integer = 0 To pl.NumberOfVertices - 2
pt1 = pl.GetPoint2dAt(i)
pt2 = pl.GetPoint2dAt(i + 1)
bul1 = pl.GetBulgeAt(i)
bul2 = pl.GetBulgeAt(i + 1)
If Math.Abs(bul1) <= 0.000001 Then
DrawLine(bmpW, bmpH, cenx, ceny, scale, New Point3d(pt1.X, pt1.Y, 0), New Point3d(pt2.X, pt2.Y, 0), g, Pens.White)
Else
Class1.BulgeToArc(pt1, pt2, bul1, pt0, rad, stang, edang)
DrawArc(bmpW, bmpH, cenx, ceny, scale, New Point3d(pt0.X, pt0.Y, 0), rad, stang, edang, g, Pens.White)
End If
Next
If pl.Closed Then
pt1 = pt2
pt2 = pl.GetPoint2dAt(0)
bul1 = bul2
If Math.Abs(bul1) <= 0.000001 Then
DrawLine(bmpW, bmpH, cenx, ceny, scale, New Point3d(pt1.X, pt1.Y, 0), New Point3d(pt2.X, pt2.Y, 0), g, Pens.White)
Else
Class1.BulgeToArc(pt1, pt2, bul1, pt0, rad, stang, edang)
DrawArc(bmpW, bmpH, cenx, ceny, scale, New Point3d(pt0.X, pt0.Y, 0), rad, stang, edang, g, Pens.White)
End If
End If
ElseIf dxfName = "INSERT" Then
Dim ext As Extents3d = ent.Bounds
DrawRect(bmpW, bmpH, cenx, ceny, scale, ext.MinPoint, ext.MaxPoint, g, Pens.Red)
DrawLine(bmpW, bmpH, cenx, ceny, scale, ext.MinPoint, ext.MaxPoint, g, Pens.Red)
DrawLine(bmpW, bmpH, cenx, ceny, scale,
New Point3d(ext.MinPoint.X, ext.MaxPoint.Y, 0),
New Point3d(ext.MaxPoint.X, ext.MinPoint.Y, 0), g, Pens.Red)
ElseIf dxfName = "TEXT" Or dxfName = "MTEXT" Then
Dim ext As Extents3d = ent.Bounds
DrawRect(bmpW, bmpH, cenx, ceny, scale, ext.MinPoint, ext.MaxPoint, g, Pens.Lime)
End If
Next
End If
''PictureBox1.Image = img
Finally
g.Dispose()
PictureBox1.Image = img
End Try
Catch ex As System.Exception
Label2.Text = ex.Message & " " & dxfName
PictureBox1.Image = Nothing
Label4.Text = "TEXT = "
Label5.Text = "MTEXT = "
Label6.Text = "ATTDEF = "
Label7.Text = "INSERT = "
Label1.Text = "図形数 = "
''_AcAp.Application.ShowAlertDialog(ex.Message)
End Try
End Using
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
Dim curItem As String = ListBox1.SelectedItem.ToString
TextBox1.Text = curItem
Dim index As Integer = ListBox1.FindString(curItem)
If Class1.BlkAry.Length > index Then
Dim objId As ObjectId = Class1.BlkAry(index).objId
DrawBlockImage(objId)
End If
End Sub
Private Sub Form2_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
With ListBox1
If .Items.Count > 0 Then
.SelectedIndex = 0
End If
End With
End Sub
End Class