Merging Point Clouds via Python

Dear Rhino Users and Developers,

I continue working on point clouds. I am trying to find a way that will merge or append few point clouds into one, and preserve their colour with python in Rhino 5.

I have found a rhinocommon method AppendNew which could help, but I don’t now how to use it. Could someone give me some advice how to succed with this task?

I guess a “brute force” way would be to create a new, empty point cloud entity, then loop through the existing pointclouds, get their point locations and colors and add them to the new point cloud. Then delete the original point clouds.

1 Like

Hi,

See if the example below makes sense to you.
I had to create 2 colored pointclouds for testing first, but the bottom part is where these 2 are merged:

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
import random


#generate 2 random pointclouds
ptc1_A = Rhino.Geometry.PointCloud()
for i in range(100):
    color = rs.coercecolor([random.randint(0,255), random.randint(0,255),random.randint(0,255)])
    pt = Rhino.Geometry.Point3d(random.random(),random.random(),random.random())
    ptc1_A.Add(pt, color)
id_A = sc.doc.Objects.Add(ptc1_A)

ptc1_B = Rhino.Geometry.PointCloud()
for i in range(100):
    color = rs.coercecolor([random.randint(0,255), random.randint(0,255),random.randint(0,255)])
    pt = Rhino.Geometry.Point3d(-random.random(),-random.random(),random.random())
    ptc1_B.Add(pt, color)
id_B = sc.doc.Objects.Add(ptc1_B)

rs.Redraw()
# Generated 2 pointclouds for testing


cloud_id_A = id_A
cloud_id_B = id_B

new_cloud_A = rs.coercegeometry(cloud_id_A)
cloud_B = rs.coercegeometry(cloud_id_B)


for cloud_B_item in cloud_B:
    pass
    new_cloud_A.Add(cloud_B_item.Location , cloud_B_item.Color)
    
sc.doc.Objects.Delete(cloud_id_B, True)
sc.doc.Objects.Replace(cloud_id_A, new_cloud_A)

does this help?
-Willem

EDIT:

as per request, below a version that includes passing on Normals

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
import random


#generate 2 random pointclouds
ptc1_A = Rhino.Geometry.PointCloud()
for i in range(100):
    color = rs.coercecolor([random.randint(0,255), random.randint(0,255),random.randint(0,255)])
    vec_n = Rhino.Geometry.Vector3d(random.random(),random.random(),random.random())
    vec_n.Unitize()
    pt = Rhino.Geometry.Point3d(random.random(),random.random(),random.random())
    ptc1_A.Add(pt, vec_n, color)
id_A = sc.doc.Objects.Add(ptc1_A)

ptc1_B = Rhino.Geometry.PointCloud()
for i in range(100):
    color = rs.coercecolor([random.randint(0,255), random.randint(0,255),random.randint(0,255)])
    vec_n = Rhino.Geometry.Vector3d(random.random(),random.random(),random.random())
    vec_n.Unitize()
    pt = Rhino.Geometry.Point3d(-random.random(),-random.random(),random.random())
    ptc1_B.Add(pt, vec_n, color)
id_B = sc.doc.Objects.Add(ptc1_B)

rs.Redraw()
# Generated 2 pointclouds for testing


cloud_id_A = id_A
cloud_id_B = id_B

new_cloud_A = rs.coercegeometry(cloud_id_A)
cloud_B = rs.coercegeometry(cloud_id_B)


for cloud_B_item in cloud_B:
    pass
    new_cloud_A.Add(cloud_B_item.Location , cloud_B_item.Normal, cloud_B_item.Color)
    
sc.doc.Objects.Delete(cloud_id_B, True)
sc.doc.Objects.Replace(cloud_id_A, new_cloud_A)
2 Likes

@Helvetosaur thank you for suggestion, but “brute force” is not the case here, as my intention is to work first on multiple point clouds files, and identify which one are required for this specific task (working on all of them would very time consuming).

@Willem I don’t know how, but it works :smiley:. Thank you very much.

1 Like