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に属性情報を書き込むことができます。その結果が以下のようになります。

「020_チェック」キーに「OK」が入力された

RhinoInsideを通してCPythonからRhinoモデルに属性情報を入力する方法を掲載しました。Rhinoの新バージョンでCPythonから3dmファイルの属性情報にアクセスできるようになったことで、用途がかなり広がりました。Rhinoだけでなく他のソフトウェアとも連携できます。今後の発展が楽しみです。それでは、最後までお読みいただきありがとうございました。

jyun-ichi

シンテグレートのプログラミング担当。入社2年目。業務はPythonやUnity(C#)の開発。運動と車と読書の田舎暮らし。

シェアする