Hi,
I saw a video on Youtube in which the author talk about creating levels inside a project using the point clouds but the author did not go to anything inside the script or make a demo video of dynamo about that, so I want to ask if anyone knows about this topic can help me?
I attached a photo of dynamo player of this project.
My guess is the author takes all points and splits them into 100mm or so layers based on their z height, then counts the number of points per layer. They take the average amount per layer, and the maximum point count and pick a likely division in that range to indicate a likely level which would logically have a lot of points. Their sensitivity value probably increases the tolerance for this ‘clamping’ point.
Alternatively they may check for a layer that has at least one point in an XY grid in a layer and assume that a layer with that much coverage is likely a level.
The Sastrugi package has nodes for dealing with point clouds and their coordinates.
To handle large clouds it looks like the author also initially decimates/reduces the points to a manageable number. My personal trick to doing this is to round point values (xyz) to the nearest X where X is a point division then using text matching in an equivalent array of values, check which have matches in your cloud. Filter the matches and turn them back to points.
i’m starting with the Sastrugi Package to select the point cloud of the project but i have some problem with the 2nd script about Scope Box to just select the point cloud of the house.
Unfortunately I’m not overly familiar with point cloud API and sastrugi personally (I use Rhino and grasshopper for cloud processing). Hopefully someone else can assist further.
You can get each plane from point cloud by using RANSAC method then create levels at each plane did you predict from point cloud.
As @GavinCrump refer you can use RANSAC method from Sastrugi package @Ewan_Opie
# Load the Python Standard and DesignScript Libraries
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import math
def indices(lst, element):
result = []
offset = -1
while True:
try:
offset = lst.index(element, offset+1)
except ValueError:
return result
result.append(offset)
pts = IN[0]
levelElevations = []
# Build a list of Z slice indices
zList = []
for p in pts:
zList.append(p.Z)
# Lowest and Highest Z Values in cloud
maxZ = int(math.floor(max(zList)))
minZ = int(math.floor(min(zList)))
# Slice the points based on their Z value into divisions (div) mm
sliceZ = []
div = 200
numSlice = int(math.floor((maxZ-minZ) / div))
ptSlices = []
for n in range(numSlice):
slice = []
zBottom = minZ+(div*n)
zTop = zBottom+div
pZList = []
if len(pts) > 0:
for p in pts:
# If a point Z is in range of this slice add it to the slice list
if p.Z > zBottom and p.Z < zTop:
slice.append(p)
pts.remove(p)
pZList.append(p.Z)
# Best fit plane through points (Floors will be horiz)
planeNorm = Plane.ByBestFitThroughPoints(slice).Normal
planeX = int(round(Vector.Normalized(planeNorm).X,1))
planeY = int(round(Vector.Normalized(planeNorm).Y,1))
planeZ = int(round(Vector.Normalized(planeNorm).Z,1))
if planeX > -0.1 and planeX < 0.1 and planeY > -0.1 and planeY < 0.1:
if planeZ > 0.9 or planeZ < -0.9:
isHoriz = True
else:
isHoriz = False
if isHoriz:
# Determine the best Z to use for a level
roundedZ = []
tol2 = 10
for pZ in pZList:
roundedZ.append(round(pZ/tol2)*tol2)
# Most frequent Z
freq = max(set(roundedZ), key = roundedZ.count)
i = roundedZ.index(freq)
levelElevations.append(pZList[i])
else:
pass
OUT = levelElevations
Sorry to bother you again. I’ve been very busy with work lately so I just had time to try the solution you suggested, I tried it but still the same error occurs.
Hope you can give me some advice, i’m not sure where this error comes from my points cloud?
Thank you so much for replying to me.
I tried the way you said by choosing the wall as the FilterElement but the result is the same. There’s always this error from Dynamo.
Do you have other ideas?