I’ve looked very hard to try and solve my challenge, and found a lot of good posts. But I cannot find this issue or tips to solve it.
I want to build a data tree with about 4 layers. In the ghpython component, there are 4 inputs, each one is part of a branch layer hierarchy, example:
Devs = {0}
Plots = {0,0}
Buildings = {0,0,0}
Massing = {0,0,0,0}
The goal is to be able to see what items are contained below each higher-order element. The tree can then be used for calculations of (# items, M2, GFA, etc.)
I want to organize the items on each lower (successive) layer underneath the item which contains them. example: Dev[1] contains Plots[3,4,5] contains Buildings[10,11,15] contains Massing[90,91,92]
Problems: My problem is that the data is duplicating and not filtering
I might be using the wrong filtering techniques (ex. Curve.Contain might be bad method)
I wanted to export one full report to CSV, Excel, or to JSON or to database. The full report would show a hierarchy of ‘ownership’ of all the geometries within other geometries - a literal hierarchy tree.
Another reason is that I want to build a tree that clearly shows the relationship between all the geometries. I need structured data which shows what geometry is inside the others, spatially. From this you can do all your calculations such as densities.
Because you add the path {0,0} that becomes the second path with three items rather than the path {1} which you were originally looking for.
I don’t know if we can assume that there are no buildings that exist outside of a plot?
import Rhino as rc
import Grasshopper as gh
import Grasshopper.Kernel.Data.GH_Path as GH_Path
import ghpythonlib.treehelpers as th
#--------------------------------------------------------
# FUNCTIONS
def rcCentroid(c):
""" Get CENTROID from CURVE """
rcCentroids = rc.Geometry.AreaMassProperties.Compute(c)
return rcCentroids.Centroid
def dataTreeGenerator(dataTree, data):
"""
Create DATA TREE from data
Args: dataTree, data
"""
dLength = len(data)
for i in range(dLength):
path = GH_Path(i)
dataTree.Add(data[i], path)
return dataTree
def rcCurveInside(curve, points):
"""Tests if POINTS (p) are inside CURVES (c) """
results = []
for p in points:
result = rc.Geometry.Curve.Contains(curve, p)
results.append(result)
return results
#--------------------------------------------------------
# EXECUTION
# construct Empty Data Tree
dTree = gh.DataTree[object]()
plotCentroids = []
for c in plots:
plotCentroids.append(rcCentroid(c))
buildingsCentroids = []
for c in buildings:
buildingsCentroids.append(rcCentroid(c))
massingCentroids = []
for c in massing:
massingCentroids.append(rcCentroid(c))
# Construct DATATREE from DEVS
dTree = dataTreeGenerator(dTree, devs)
print dTree
#print type(dTree)
#print dTree.Path(0)
print dTree.Branch(1)
#print dTree.BranchCount
# Iterate the first layer of branches
for i in range(dTree.BranchCount):
branchData = dTree.Branch(GH_Path(i))
branchPath = dTree.Path
# get the curves in each branch
for j in branchData:
# get both items of PLOT CURVE and PLOT CENTROID
for plot, centroid in zip(plots, plotCentroids):
# test inclusions
result = rc.Geometry.Curve.Contains(j, centroid)
print result
print i
# filter by inclusion to create tree
if result == rc.Geometry.PointContainment.Inside:
dTree.Add(plot, GH_Path(i,0))
for building, centroid2 in zip(buildings, buildingsCentroids):
result = rc.Geometry.Curve.Contains(plot, centroid2)
if result == rc.Geometry.PointContainment.Inside:
dTree.Add(building, GH_Path(i,len(dTree.Branch(GH_Path(i,0)))-1,0))
for mass, centroid3 in zip(massing, massingCentroids):
result = rc.Geometry.Curve.Contains(building, centroid3)
if result == rc.Geometry.PointContainment.Inside:
dTree.Add(mass, GH_Path(i,len(dTree.Branch(GH_Path(i,0)))-1,len(dTree.Branch(GH_Path(i,len(dTree.Branch(GH_Path(i,0)))-1,0)))-1,0))
Maybe see if the above code is what you are looking for.