AutoCADマクロ屋本舗 掲示板


true colorで設定された色をインデックスカラーへ一括変更したい

1:タイ :

2024/04/26 (Fri) 14:18:21

お世話になっております。

ただ今ユーザーに複数オブジェクトを選択させ、
その中にtrue colorで色の設定がされているオブジェクトがあれば、
その色に近しいインデックスカラーに設定を置き換えるautolispを作成中です。

色々検索して、
グループコード62がインデックスカラー、420がtrue colorを示すということがわかり、
https://www.theswamp.org/index.php?topic=52761.msg576434#msg576434
このページに載っているコードをchatGPTでautolispに変換するなど色々して


【以下のコードを読む意味はあんまりないかもです】
(defun c:ACItoRGBLookup ()
(list
(cons 1 '(255 0 0)) (cons 2 '(255 255 0))
(cons 3 '(0 255 0)) (cons 4 '(0 255 255))
(cons 5 '(0 0 255)) (cons 6 '(255 0 255))
;; 他のすべてのACI値に対応するRGB値を続ける...
;; ACI 1から255までの値と対応するRGB色(赤、緑、青の順)を指定
(cons 255 '(255 255 255))
)
)

;; 与えられたRGB値に最も近いACIを見つける関数
(defun c:FindClosestACI (r g b / aci-rgb-list min-dist aci color-diff rgb-list)
(setq aci-rgb-list (c:ACItoRGBLookup))
(setq min-dist 1e+8) ;; 最小距離を非常に大きな数で初期化
(setq aci 0)
;; 与えられたRGB値と各ACI値のRGB値との距離を計算し、最小距離のものを見つける
(foreach item aci-rgb-list
(setq rgb-list (cdr item))
(setq color-diff
(+ (expt (- r (nth 0 rgb-list)) 2)
(expt (- g (nth 1 rgb-list)) 2)
(expt (- b (nth 2 rgb-list)) 2)))
(if (< color-diff min-dist)
(progn
(setq min-dist color-diff)
(setq aci (car item))
)
)
)
aci
)

;; ユーザーにオブジェクトを選択させ、各オブジェクトの情報を表示し、色を近いインデックスカラーに変更する
(defun c:ReplaceColorsWithACI ()
(setq ss (ssget))
(if ss
(progn
(setq len (sslength ss))
(repeat len
(setq ent (ssname ss (setq i (1- len))))
(setq entdata (entget ent))
(setq objtype (cdr (assoc 0 entdata)))
(setq objname (cdr (assoc 330 entdata)))
(setq color (cdr (assoc 62 entdata)))
(princ (strcat "\nObject: " objtype " Handle: " handle " Color Index: " (itoa color)))
(if (and (/= color 0) (/= color 256)) ;; 現在の色がBYLAYERかBYBLOCKでない場合のみ変更
(progn
(prin1 objname)
(princ (strcat "はBYLAYERでもBYBLOCKでもない"))
(setq rgb (cdr (assoc 420 entdata))) ;; RGB値が設定されていれば、それを基に最も近いACI値を見つけて変更
(if rgb
(progn
(setq r (lsh rgb -16))
(setq g (lsh (logand rgb 65280) -8))
(setq b (logand rgb 255))
(princ (strcat "\nR:" (itoa r) " G:" (itoa g) " B:" (itoa b)))
(setq closest-aci (c:FindClosestACI r g b))
(princ (strcat "\nObject: " objtype " Handle: " handle " RGB(" (itoa r) ", " (itoa g) ", " (itoa b) ") -> ACI: " (itoa closest-aci)))
(setq entdata (subst (cons 62 closest-aci) (assoc 62 entdata) entdata))
(entmod entdata)
)
)
)
)
)
)
(princ "No objects selected.")
)
(princ)
)

(princ "\nType 'ReplaceColorsWithACI' to run.")
(princ)


ここまでできたのですが、こちらを実行してから実行後のオブジェクトのプロパティを見ても
色の設定がインデックスカラーによるものになっておらず、true colorのままです。
コマンド実行後にそのオブジェクトのDXF図形情報を見てみるとグループコード62は想定した数字になっているのですが、
なんならコマンド実行前の、新しくオブジェクトを作成して色をBylayerからtrue colorで全く別の色にしただけの段階でDXF図形情報を見ても、
グループコード62はグループコード420で表された色に近しい色の番号になっているのです。
(ということはこのコマンドはまったく何の意味も成さないということでしょうか?)

ここで、お聞きしたいことが2点あります。
① このコマンドを修正し、true colorで色が設定されたオブジェクトを
  それに近しい色のインデックスカラーに書き換えられるものにするにはどうすればよいでしょうか?
② ①が実現したら、選択したオブジェクトの中に色設定がBYLAYERやBYBLOCKのものがあれば、
  その場合はレイヤーやブロックの色設定をtrue colorからインデックスカラーに書き換えたいと思っています。
 この場合、最終的にどのようなコードに変更すれば宜しいでしょうか?

一応、何故このようなことをしたいかと申しますと
普段図面を印刷する際、true colorで色を設定したオブジェクトのみカラーで、その他はすべて黒色で印刷されるように設定しているため
外部からtrue colorのオブジェクトまみれの図面をもらった際、カラフルすぎる図面が印刷されないよう、
true colorのオブジェクトの色設定を一括でインデックスカラーへ変更したいからです。

使用CADはAutoCAD2023です。
どうぞ宜しくお願いいたします。
2:んぼ :

2024/04/26 (Fri) 15:05:17

処理的には420を抜けばよいっぽいですがいかがでしょうか?


(defun c:test ( / ss i ent)
(vl-load-com)
(setq ss (ssget)
i 0
)
(repeat (sslength ss)
(setq ent (entget (ssname ss i)))
(entmod (vl-remove (assoc 420 ent) ent))
(setq i (1+ i))
)
)
3:LUNE :

2024/04/26 (Fri) 15:30:59

線を1本描いて、(entget (car (entsel)))をやってみます。

ケース1:色がBylayer→コード62も420もなし
((-1 . <図形名: 1d2c829ec30>) (0 . "LINE") (330 . <図形名: 1d2c82a69a0>) (5 . "A2E3") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "KEIKAKU") (100 . "AcDbLine") (10 6660.94 48324.9 0.0) (11 42568.5 59989.0 0.0) (210 0.0 0.0 1.0))

ケース2:色を水色(インデックス4)に変更→ (62 . 4) が出現
((-1 . <図形名: 1d2c829ec30>) (0 . "LINE") (330 . <図形名: 1d2c82a69a0>) (5 . "A2E3") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "KEIKAKU") (62 . 4) (100 . "AcDbLine") (10 6660.94 48324.9 0.0) (11 42568.5 59989.0 0.0) (210 0.0 0.0 1.0))

ケース3:色を(0,225,225)に変更→(62 . 4) (420 . 65535)が出現
((-1 . <図形名: 1d2c829ec30>) (0 . "LINE") (330 . <図形名: 1d2c82a69a0>) (5 . "A2E3") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "KEIKAKU") (62 . 4) (420 . 65535) (100 . "AcDbLine") (10 6660.94 48324.9 0.0) (11 42568.5 59989.0 0.0) (210 0.0 0.0 1.0))

ケース3からケ-ス1に戻すと、(62 . 4) (420 . 65535)の両方が消え、ケース3からケース2に戻すと、(420 . 65535)が消えます。
ここから推測できることは、コード62とコード420があった場合は、コード420が有効になるということです。

そしてさらに試してみます。ケース3で変更したものを異なるtrue colorに変更します。
ケース4:色を(0,225,225)にしたもの)を(237,31,36)に変更。
((-1 . <図形名: 1d2c829ec30>) (0 . "LINE") (330 . <図形名: 1d2c82a69a0>) (5 . "A2E3") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "KEIKAKU") (62 . 240) (420 . 15540004) (100 . "AcDbLine") (10 6660.94 48324.9 0.0) (11 42568.5 59989.0 0.0) (210 0.0 0.0 1.0)

ここで注目すべきは、(62 . 240) (420 . 15540004)です。
変更したのは、true colorなのに、インデックスカラーの62も近似色に変更されています。
ということは、対応表がなくても、近似色は自動的に設定されると考えられます。
これは、おそらくtrue color対応がないバージョンへの対策だと思われます。

ということは、やるべきことは、コード420のドットペアを削除すればいいのでは?

こんな感じでしょうか。

--------------------------------------------------------
(defun c:ct2i ( / ss cnt ent flst blst)
(setq ss(ssget))
(setq cnt 0)

(repeat (sslength ss)
(setq ent (entget (ssname ss cnt)))
(setq blst (cdr(member (assoc 420 ent) ent)))
(setq ent (reverse ent))
(setq flst (reverse (cdr (member (assoc 420 ent) ent))))
(setq ent (append flst blst))
(entmod ent)
(setq cnt (+ cnt 1))
)
(princ)
)
4:LUNE :

2024/04/26 (Fri) 15:31:36

んぽさんに先越された(´▽`*)
5:LUNE :

2024/04/26 (Fri) 15:44:56

② ①が実現したら、選択したオブジェクトの中に色設定がBYLAYERやBYBLOCKのものがあれば、
  その場合はレイヤーやブロックの色設定をtrue colorからインデックスカラーに書き換えたいと思っています。
 この場合、最終的にどのようなコードに変更すれば宜しいでしょうか?

まずBylayerの場合から
コード62がないor(62 . 256)であるがBylayerの状態なので、その場合は、コード8の画層名を取得します。
次に(tblsearch "layer" [画層名])で画層の設定が取得できるので、そのコード62から色を取得し、(62 . [インデックス]) のドットペアをオブジェクトのリストに付加します。
(レイヤーにtrue colorが設定されていても、tblsearchでは出てきませんね・・・)

Byblockの場合は、(62 . 0)なので、ブロック内部のオブジェクトの場合は、親オブジェクトのコード62を読み取って、それを設定すればよいかと。
6:タイ :

2024/04/30 (Tue) 10:56:16

お二人共お早い回答ありがとうございます!
どちらも想定通りに動きました。

2通りのドットペアの取り除き方を学べて良かったです。
また、true colorとインデックスカラーについての仕様の検証もありがとうございます。

②についてのアドバイスも、ありがとうございます!
いただいたアドバイスをもとに、lisp作成してみたいと思います。
あらためてお二人共本当にありがとうございました。

  • 名前: E-mail(省略可):
  • 画像:

Copyright © 1999- FC2, inc All Rights Reserved.