RhinoInsideを用いてCPythonから属性ユーザテキストに書き込む(QRコード編)
BIMの重要な要素に属性情報があります。仕様や数量などの情報をモデルデータに埋め込み、生産設計や施工管理等に活用することができます。
前回は、Excelからワークセッションの各3dmファイルオブジェクト属性情報を編集しました。入力する数が少ないうちは手入力で十分なのですが、項目数が多くなったときに作業負荷が大きくなり、入力ミスが出てくると考えられます。
そこで本記事では、CPythonのRhinoInsideモジュールとQRコードを読み込む方法で、属性情報の入力を簡略化する方法を示します。CPythonのPyQRCodeモジュールを用いてQRコードを出力して、そこにモデルのファイル名と名前を埋め込み、WebカメラでQRコードを読み込むことで入力作業を簡略化します。それからRhino InsideによってCPythonから3dmファイルを読み込んで、属性ユーザテキストに情報を書き込むことができます。この一連の処理によって属性情報の手入力の間違いを減らすことができます。
CPythonモジュールのインストール
まず、CPythonはあらかじめインストールされていることを想定します。パッケージ管理システムのPIPで以下のモジュールをインストールします
・RhinoInside ※Rhinoバージョン7,64bit CPython(2.7, 3.5, 3.6, 3.7),
・PyQRCode
・Pillow
・opencv-python
QRコードの出力
次に、前回使用したExcelからファイル名とオブジェクト名を取得して、QRコード画像を生成します。後述のCPythonコードを実行すると下のようなQRコード画像の一覧が生成されます。
### Copyright (c) 2021 Syntegrate
###
### This software is released under the MIT License.
### https://opensource.org/licenses/MIT
# -*- coding: utf-8 -*-
import os, sys
import traceback
#QR画像の出力
import qrcode
#RhinoInsideの使う
import rhinoinside
rhinoinside.load()
import System
import Rhino
#このPythonファイルへのディレクトリパス
dir_home = os.path.dirname(__file__)
#QRコード画像を保存するディレクトリ(なければ作成)
dir_save_qr = os.path.join(dir_home, "qr")
#Pythonファイルへのディレクトリに最初に作成した3dmファイルを指定
path_3dm = os.path.join(dir_home, "panelize.3dm")
#3dmファイルを読み込んで、タプル(3dmの名前, objの名前)のリストを構築
def build_list_strQR():
#結果
list_tup_name3dm_nameobj = []
name_3dm = os.path.basename(path_3dm)
#3dmファイルをRhinoInsideで開く
f3dm = Rhino.FileIO.File3dm.Read(path_3dm)
#3dmファイル内のオブジェクトを巡回, 名前があればTuppleにしてリストにセット
for obj in f3dm.Objects:
atrb = obj.Attributes
if atrb is None:
continue
if obj.Name is None:
continue
list_tup_name3dm_nameobj.append((name_3dm, obj.Name))
f3dm.Dispose()
return list_tup_name3dm_nameobj
#QRを指定ディレクトリ書き出し
def generate_qr(list_tup_name3dm_nameobj):
#ディレクトリがなければ作成
if not os.path.exists(dir_save_qr):
os.mkdir(dir_save_qr)
#QR画像をPNG形式で保存
for name_3dm, name_obj in sorted(list_tup_name3dm_nameobj)[:30]:
# PNGパス
name_file = os.path.splitext(name_3dm)[0]
path_qr = os.path.join(dir_save_qr, name_file + "-" + name_obj + ".png")
# QR
data = name_3dm + "," + name_obj
img = qrcode.make(data)
# 保存
img.save(path_qr)
# 出力
print("exported : {}, {}".format(name_3dm, name_obj))
def main():
try:
#3dmファイルを読み込んで、タプル(3dmの名前, objの名前)のリストを構築
list_tup_name3dm_nameobj = build_list_strQR()
#QRを指定ディレクトリ書き出し
generate_qr(list_tup_name3dm_nameobj)
except:
traceback.print_exc()
if __name__ == '__main__':
main()
QRコードを読み込んで属性情報を入力
このQRコードを用紙やシールに印刷してWebカメラで読み込めるようにします。QRコードにはファイル名とオブジェクト名が埋め込まれています。後述のCPythonでカメラ画面をカメラに写してQRコードを読み込むと、任意の3dmファイル内のオブジェクトの属性情報(今回は「020_チェック」)に”OK”と入力します。
### Copyright (c) 2021 Syntegrate
###
### This software is released under the MIT License.
### https://opensource.org/licenses/MIT
# -*- coding: utf-8 -*-
import os, sys
import cv2
import numpy as np
#RhinoInsideの使い方
import rhinoinside
rhinoinside.load()
import System
import Rhino
#excelのパス
dir_home = os.path.dirname(__file__)
#カメラからQRコードの情報を取得する
def read_qr():
#open-cvによるカメラ取得
cap = cv2.VideoCapture(2)
detector = cv2.QRCodeDetector()
ret = False
name_3dm = ""
name_obj = ""
while True:
_, img = cap.read()
data, points, straight_qrcode = detector.detectAndDecode(img)
if data:
print('decoded data: {}'.format(data))
list_data = data.split(",")
name_3dm = list_data[0]
name_obj = list_data[1]
ret = True
break
# display the result
cv2.imshow("img", img)
if cv2.waitKey(1) == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
return ret, name_3dm, name_obj
#3dmファイルのオブジェクト属性情報に入力
def write_key_value(name_3dm, name_obj):
path_3dm = os.path.join(dir_home, name_3dm)
f3dm = Rhino.FileIO.File3dm.Read(path_3dm)
#3dmファイル内のオブジェクトを巡回し、名前が一致すればUserTextをセット
for obj in f3dm.Objects:
atrb = obj.Attributes
if atrb is None:
continue
if atrb.Name != name_obj:
continue
atrb.SetUserString("020_チェック", "OK")
print("{}({}), 020_チェック : OK".format(name_3dm, name_obj))
f3dm.Write(path_3dm, version=7)
f3dm.Dispose()
def main():
#カメラからQRコードの情報を取得する(qボタンで終了)
ret, name_3dm, name_obj = read_qr()
if not ret:
print("QRコードを読み込めませんでした")
return
#3dmファイルのオブジェクト属性情報に入力
write_key_value(name_3dm, name_obj)
if __name__ == '__main__':
main()
上のコードを実行することで、QRコードを読み込むだけで3dmに属性情報を書き込むことができます。その結果が以下のようになります。
RhinoInsideを通してCPythonからRhinoモデルに属性情報を入力する方法を掲載しました。Rhinoの新バージョンでCPythonから3dmファイルの属性情報にアクセスできるようになったことで、用途がかなり広がりました。Rhinoだけでなく他のソフトウェアとも連携できます。今後の発展が楽しみです。それでは、最後までお読みいただきありがとうございました。