🌌

Cinema4Dへの点群の読み込み

2025/02/14に公開

DCCツール「Cinema4D」へ点群を読み込む方法をまとめました。

正しく表現すると、「点群を読み込む」というよりもスクリプトを使用し用意した点群データから頂点カラータグのついたデータに変換するというものです。

フォトグラメトリモデルをDCCツールで編集する際にレーザースキャンした点群をガイドにしたい場合などにも便利です。

手順

①点群データの準備と調整

座標と色の「x,y,z,r,g,b」の構成の点群データを用意する。
区切りはスペース。

例)

14.54867172 14.17017174 4.43618011 0.196078 0.180392 0.180392
14.52911377 14.22664928 4.46986389 0.239216 0.211765 0.196078
14.49718666 14.19209480 4.43062592 0.227451 0.211765 0.2
14.37869453 14.19043446 4.36045074 0.352941 0.298039 0.270588
14.40212631 14.17935371 4.37358093 0.32549 0.270588 0.243137
14.41651154 14.21537113 4.39701080 0.278431 0.231373 0.211765
14.37312508 14.26291943 4.39273071 0.282353 0.243137 0.223529
14.34361076 14.27568913 4.37908173 0.254902 0.223529 0.211765
︙

用意する点群ファイルはCloudCompareからアスキー形式で書き出すと簡単。
データの初めや各行に余計な文字が含まれていると後述のスクリプト実行時にエラーになるので注意。
上記の例のようなシンプルな座標と色のみのデータとする。

CloudCompareからの書き出し設定。 

「separator」はspace
「order」はpoint(座標)の次にcolor(色)の順番になっているものにする。
「Save color as float values (0-1)」は無効にする。利用するスクリプトのカラーがデフォルトではfloat0-255の値を使用しているため。

ここでは「Test.txt」として保存する。
(アスキーデータになっていれば拡張子は何でも良い)

②Cinema4Dで読み込み変換

Cinema4Dを起動しスクリプトマネージャを表示する。

新規スクリプトを作成。

以下のスクリプトを貼り付け、5行目のpts_file部分を、上記手順で用意した「Test.txt」の点群ファイルのパスに書き換える。
※スクリプトはこちらのサイトで紹介されているものを利用させていただきました

import c4d
from c4d import gui

# This path should point to your PointCloud file you want to read in.
pts_file = r"D:\Test.txt"

# Main function
def main():
    doc = c4d.documents.GetActiveDocument()
    num_points = sum(1 for line in open(pts_file))
    print("Lines: " + str(num_points))
    new_obj = c4d.PolygonObject(num_points,0)
    vtx_color_tag = c4d.VertexColorTag(num_points)
    vtx_color_tag.SetPerPointMode(True)
    data = vtx_color_tag.GetDataAddressW()
    print (vtx_color_tag)
    print (data)
    points = new_obj.GetAllPoints()
    normals = new_obj.GetAllPoints()
    colors = new_obj.GetAllPoints()

    with open(pts_file,"r") as pts:
        idx = 0
        for line in pts:
            values = line.split(" ")
            points[idx] = c4d.Vector(float(values[0]),float(values[1]),float(values[2]))
            
            # Use this code line to convert RGB float values to integer RGB values - like 0.354 to 255.
            # colors[idx] = c4d.Vector(float(values[3]),float(values[4]),float(values[5]))
            
            # Use this code line to convert integer RGB values to float values - like 255 to 0.354.
            colors[idx] = c4d.Vector(float(values[3])/255.0,float(values[4])/255.0,float(values[5])/255.0,)
            
            c4d.VertexColorTag.SetColor(data, None, None, idx, colors[idx])
            idx += 1
        new_obj.SetAllPoints(points)
        vtx_color_tag[c4d.ID_VERTEXCOLOR_DRAWPOINTS] = True
        new_obj.InsertTag(vtx_color_tag)
        doc.InsertObject(new_obj)
        c4d.EventAdd()

# Execute main()
if __name__=='__main__':
    main()

右下のボタンから実行する。

  • 実行ボタンを押しても何も起きない場合
    • エラーが発生しているので、コンソールウィンドウを開き確認する。

    • エラー内容に応じて対応する。

正しく変換されると画面上に点群が表示される。

読み込まれたデータは「ポリゴン」という名称になっているが実際はポリゴンはなく頂点カラータグで表現されたデータとなっている。

以上!🍅

エラーと対策編

  • 点群の色が真っ黒や真っ白になってしまう場合
    • RGBの色変換が間違っている
    • 用意した点群の色が0~1のfloatを使っているのか0~255のintを使っているのかに応じて、スクリプトの28行~32行部分を変更する
      • 0~1のfloatのRGBを使っているなら29行目を利用する
      • 0~255のintのRGBを使っているなら32秒目を利用する
ホロラボのテックブログ

Discussion