Process list of point3d and create pointcloud object


(Rajeshupadhayaya) #1

Hi All,

I have recently started python in Gh and got stuck. I have a problem where i receive list of point3d at Pts variable and then i need to convert this Pts list to pointcloud and find the nearest point and then draw a line from current point to nearest point. Below is my code.

import rhinoscriptsyntax as rs
import Rhino as rc

def RunCommand(Pts, id0, maxn, maxdist, A):  
    try:
        p = rs.PointCloudPoints(Pts)
        p = Pts
        polylines = []
        i = 0
        if p:
            while len(p)>0 and i < maxn:
                
                polys = PseudoSteinerTrees2(p, maxdist, maxn, id0)
                
                if(len(polys) >0):
                    polylines.append(polys)
                i += 1
        A = polylines
#        print(A)
    except:
        print("Unexpected error:")
        raise
        
    


def PseudoSteinerTrees2(p, maxdist, maxn, id0):
    triLines  = []
    p0 = 0
    p1 = 0
    p2 = 0

    cp = 0
#    print(p)
    i = 0
    while len(p)>1 and i<maxn:
        p0 = p[0 % len(p)]
#        print(p0)
        p.pop(0 % len(p))

        cp = p.PointArrayClosestPoint(p0)
#        cp = p.index(p0+1)
        p1 = p[cp]
#        p1 = p[1]

        distance = p0.DistanceTo(p1)
        if distance > maxdist:
            break
        p01 = (p0 + p1) * 0.5
#        p.RemoveAt(cp)
        triLines.append(rc.Geometry.Polyline([p0,p01,p1]))
        p0 = p01
        i += 1
    return triLines
                        
##
#if "__name__" == "__main__":
#    print('running...')
#Runcommand1(x)

RunCommand(Pts, id0, max, maxDist, A)

Pts has data:
[<Rhino.Geometry.Point3d object at 0x000000000000003F [-0.502662831685814,-0.778512045637943,-0.0659786402555083]>,
<Rhino.Geometry.Point3d object at 0x0000000000000040 [0.712929626793102,0.547407993836053,-0.822306199847863]>,
<Rhino.Geometry.Point3d object at 0x0000000000000041 [-0.807991005390878,0.903379673093268,-0.0348241026675442]>,
<Rhino.Geometry.Point3d object at 0x0000000000000042 [0.722341490780162,0.890367296473294,0.944099398303823]>,
<Rhino.Geometry.Point3d object at 0x0000000000000043 [0.73663112695172,-0.974628488521384,0.927980866249642]>,
<Rhino.Geometry.Point3d object at 0x0000000000000044 [-0.795870615074351,0.0201654178184296,-0.96995095348449]>]

Image:
for%20formum


(Graham) #2

Hi, you have used a mix of different quote marks so your formatting is all messed up. You should be able to replace these with backticks ```python


(Rajeshupadhayaya) #4

I’ve corrected the code…


(jesterKing) #5

It’d help if you showed the actual error message in the panel as well (instead of clipping the image there)


(Rajeshupadhayaya) #6

here is the error:


(jesterKing) #7

Instead of using rhinoscriptsyntax you’re probably better of using RhinoCommon directly to create your PointCloud

https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_PointCloud__ctor_2.htm


(Graham) #8

Hi it looks like you were right first time with the ˋrs.AddPointCloud` method - did that fail as well?
PointCloudPoints gets the point coordinates.


(Rajeshupadhayaya) #9

with AddPointCloud, I am getting below error:

Runtime error (NotSupportedException): This type of object is not supported in Grasshopper, so this Python script cannot create it. You might want to use 'scriptcontext.doc = Rhino.RhinoDoc.ActiveDoc' to use the Rhino doc, instead? If you do, remember to restore it: 'scriptcontext.doc = ghdoc'.

Traceback:
  line 125, in AddPointCloud, "C:\Users\user\AppData\Roaming\McNeel\Rhinoceros\6.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib\rhinoscript\geometry.py"
  line 9, in RunCommand, "<string>"
  line 63, in script

However rc.Geometry.PointCloud (import Rhino as rc) is working and python is working fine without error but other component is not able to understand that data.


#10

Grasshopper does not currently support Pointcloud entities (IIRC).


#11

hang on a second, do you actually need a PointCloud Object? Does another part of your workflow (not described in this post) rely on PointClouds?

if this part is indeed what you want to do, you can find the nearest point in a python list (by brute force) without it being a point cloud object.

if you need performance you can use the RTree datastructure which is an efficient spatial search, but more work to set up.

Here are two options for finding the closest point. one is just python and points, the other uses the PointCloud.ClosestPoint method.

I wrapped the pointcloud in another python class so you can pass it between components. Extracting the data is pretty straightforward (bottom left python window, you can get the location as a point, the color and normal Vector)

Hope this helps you!


pointclouds.gh (13.7 KB)


#12

The Point3dList class is also fairly well optimised I find (for finding closest points/indices etc).


(Michael Pryor) #13

Agree. Probably my favorite method in Rhinocommon: https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Collections_Point3dList_ClosestIndex.htm

Does same as point cloud but works in gh without any wrapping.