Convert Point cloud to revit element mesh by using python 3 and Open3d

Point_Cloud_To_Mesh.dyn (57.5 KB)
Hi
I need to share with you how to convert point cloud to mesh by using use python 3 and “Open 3d” Package in dynamo

1- load Open 3d packedge in to your dynamo
2- voxel_down_sampl
downpcd=pcd.voxel_down_sample(voxel_size=0.05)
3- used dbscan to cluster point cloud and remove the noise point
labels1 = np.array(downpcd.cluster_dbscan(eps=0.05, min_points=10))
4- create mesh TriangleMesh by using point cloud ball pivoting algorithm o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(rest,o3d.utility.DoubleVector([1radius, radius2]))

5- creat dynamo mesh and convert it to revit element

image



http://www.open3d.org/

"""

Create by Ramiz Mohareb
13-12-2021
enramiz@yahoo.com
this code use Open 3d Pack. http://www.open3d.org/
Important! This code will only work with Dynamo versions
that are able to run cPython3 and have the following ad
[Point_Cloud_To_Mesh.dyn|attachment](upload://jH5GTaDZtlEoPjKCGgGjD42Bpyj.dyn) (57.5 KB)
ditional 
python packages installed.

Packages required:
Open3d 
numpy

"""

import random
import numpy as np
import clr
import open3d

#libraries used
import numpy as np
import open3d as o3d

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import matplotlib.pyplot as plt


filepath=IN[0]


import numpy as np
import open3d as o3d


filepath=IN[0]
segment_models={}
segments={}
inliers={}
inlier_cloud={}

Outt=[]
Outt2=[]
Outt3=[]
dec_meshL=[]
max_plane_idx=1
point_cloud= np.loadtxt(filepath,skiprows=1)



#Format to open3d usable objects
pcd = o3d.geometry.PointCloud()


pcd.points = o3d.utility.Vector3dVector(point_cloud[:,:3])
pcd.colors = o3d.utility.Vector3dVector(point_cloud[:,3:6]/255)
pcd.normals = o3d.utility.Vector3dVector(point_cloud[:,6:9])


downpcd=pcd.voxel_down_sample(voxel_size=0.1)



labels1 = np.array(downpcd.cluster_dbscan(eps=0.05, min_points=10))
candidates1=[len(np.where(labels1==j)[0]) for j in np.unique(labels1)]
best_candidate1=int(np.unique(labels1)[np.where(candidates1== np.max(candidates1))[0]])

rest=downpcd.select_by_index(list(np.where(labels1== best_candidate1)[0]))    


    
    
distances = rest.compute_nearest_neighbor_distance()
avg_dist = np.mean(distances)
radius = 1 * avg_dist
    
    #computing the mehs

bpa_mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(rest,o3d.utility.DoubleVector([1*radius, radius*2])) 
#dec_mesh1 = bpa_mesh.filter_smooth_simple(number_of_iterations=1)
dec_mesh1 = bpa_mesh.filter_smooth_taubin(number_of_iterations=10)
dec_mesh3=dec_mesh1
dec_mesh3.remove_degenerate_triangles()
dec_mesh3.remove_duplicated_triangles()
dec_mesh3.remove_duplicated_vertices()
dec_mesh3.remove_non_manifold_edges()
   # Outt.append(np.asarray(segments[i].Points).tolist())
Outt2.append(np.asarray(dec_mesh3.triangles).tolist())
Outt3.append(np.asarray(dec_mesh3.vertices).tolist())
 
 

    
#o3d.visualization.draw_geometries([segments[i] for i in range(max_plane_idx)]+[rest])
#
OUT = Outt2,Outt3




11 Likes

Super!!

1 Like

Nice work @RMohareb :+1:
Open3D has a fantastic set of tools, and its great we can now use them with the new Python version included with Dynamo.

1 Like

Hi @Ewan_Opie
I have been waiting for your comment :wink:

You are right, Python 3 give us a powerful path to create new generation of dynamo tools. As in your new nodes or in the above example we can create that by load a powerful Python pakedge. I expect more new dynamo packages generation for the in the next a few month

Hi @RMohareb ,

I tried running your code, however I don’t understand how to install Open3D or numpy, do I have to install these packages through Dynamo? (I can’t find them in the Package Searcher).

Also what version of Revit and Dynamo are you using?

Kind regards,
Daan

Hi @Daan

First this code must be run at python 3 thats mean you need revit 2022 with dynamo suport Python 3.
to install Open3d, numpy or any pakedge suport by python 3
please folows the below link
image
to install Open3d:
use CMD and write “pip instrall Open3d”

1 Like

Thanks a lot for the quick reply! I’ll get back to you if i finish the toturial

1 Like

@Daan you are welcome
also this link maybe help you

2 Likes

Would you be kind of sharing with us the textFile as I am a bit confused with the normals columns as It seems to be an input that must be passed through the BPA algorithm, thanks in advance

Hi @MiguelGT17

if you use PTS format the file already include the normal vector as shown in the below pic.
if your file not include the normal vector you can use Open3d to estimate it.

http://www.open3d.org/docs/release/tutorial/geometry/pointcloud.html#Visualize-point-cloud


2 Likes

thanks for answer me and for the insights, appreciate it RMohareb!
Cheers

1 Like

Great job

1 Like

The script worked for my point cloud, but resulted many “NaN” values and Dynamo can not accept them… How to remove them from the list? I tried many nodes and is not working…

Was wondering if there’s an equivalent for the nodes on Civil 3D for “DirectShape.ByMesh”

And i’m using a LAS file for my point cloud i guess the .PTS is the almost the same format ?

Closest I can think of is Object.ByGeometry, but it may not work on a mesh.

1 Like

I still haven’t had time to explorer this but in the next weeks since it’s downtime in production ill test it out and come back with trying to adapt this into Civil 3D

Ill keep ya folks posted !

1 Like