How to visualize normals of point clouds with normals?


#1

Hello,

I have a point clouds in a very simple text format where each line is composed of the following informations (separated by ,):

x, y, z, Nx, Ny, Nz

I can import this point cloud into Rhino and see the points but I cannot figure how to visualize the normal information. Is it lost during importation?

I wish I could add some kind of arrow starting from each point and pointing in the normal direction. Is there something like this directly in Rhino or does someone has any Idea on how to do it in Python?

Thanks


#2

Since points, conceptually, don’t have normals, I suppose the normal information is lost. However, since it’s your script and you can read the numbers and do what you’d like with them, there is probably no reason why you can’t compute your own visual to show them. Just a short line with an arrowhead, or something that makes sense to you.


#3

Hi Bruno,

Rhino supports pointclouds with shaded normals. You can use below python script to import your file. Please note that the script requires no seperators (the comma) between the 6 float values in the file. It expects that there are spaces between floats:

import Rhino
import scriptcontext
import rhinoscriptsyntax as rs
import System

def Import_npts():
    filter = "PointNormal (*.npts)|*.npts|All Files (*.*)|*.*||"
    filename = rs.OpenFileName("Open points with normals file", filter)
    if not filename: return

    file = open(filename, "r")
    contents = file.readlines()
    file.close()

    cloud = Rhino.Geometry.PointCloud()
    npoint = Rhino.Geometry.Point3d.Unset
    normal = Rhino.Geometry.Vector3d.Unset

    rs.StatusBarProgressMeterShow(" Processing", 0, len(contents), True, True)
    rs.Prompt("Processing, please wait")

    for i, line in enumerate(contents):
    items = line.strip("()\n").split(" ")
    if not items[0].startswith("nan"):
        npoint.X = float(items[0])
        npoint.Y = float(items[1])
        npoint.Z = float(items[2])
        normal.X = float(items[3])
        normal.Y = float(items[4])
        normal.Z = float(items[5])
        cloud.Add(npoint, normal)
        if (i%50000) == 0: rs.StatusBarProgressMeterUpdate(i)

    rs.Prompt()
    rs.StatusBarProgressMeterHide()

    if cloud.IsValid:
        scriptcontext.doc.Objects.AddPointCloud(cloud)
        scriptcontext.doc.Views.Redraw()
        print "One poincloud with normals build from", file.name

    cloud.Dispose()

if (__name__ == "__main__"):
    Import_npts()

you can of course change the script to allow custom seperators. I suggest to use _EditPythonScript and paste it into the editor to run it first. The expected file type is *.npts but you can usually use any file extension.

c.


#4

Great advice! Thanks to all!


#5

I tried this script. 1st I got an indent message. I fixed that, now I get argument message:

Message: readlines() takes at least 1 argument (0 given)

Traceback:
line 12, in , “C:\Users\Me.Me\AppData\Local\Temp\TempScript.py

Not sure what to do with this?


#6

After correcting indentation, everything works fine on my computer. Sorry!


#7

Well then I’ll ask the dumb question. what exactly did you do other than the indent? In other words, what procedure did you use to run it in Rhino? I tried Runpythonscript and Editpythonscript. Both gave me that last error on either WIP or V5.


#8

I just started Editpythonscript, created a new empty script (here) and run it.Test.txt (16.6 KB)
ReadPts.py (1.4 KB).

Good luck!

P.S.: I also might have multiple version of Python installed on my computer for other purpose. Hope it’s not that…


#9

I’ll Try the ReadPts.py. That error message I posted came from the EditPythonScript as I was debugging it. So I wonder if there is something to having more than on Python that reads it correctly? But I’ll try the one you posted.