Last active
May 13, 2021 08:17
-
-
Save ian-quinn/89b72eb09797726cb3aa9050008fc58d to your computer and use it in GitHub Desktop.
[component_ghpython] Useful GH_Python components #grasshopper #python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Switch on and off of the global timer | |
# Needs update with Rhino 7 | |
import Grasshopper as gh | |
# Get the Grasshopper document and objects | |
ghDoc = ghenv.Component.OnPingDocument() | |
ghObjects = ghDoc.Objects | |
# Iterate the GH objects, check type and reset data recorders | |
for obj in ghObjects: | |
if type(obj) is gh.Kernel.Special.GH_Timer: | |
if Toggle: | |
obj.Locked = True | |
obj.ExpireSolution(True) | |
else: | |
obj.Locked = False | |
obj.ExpireSolution(True) | |
# RegionContainment defines enumerated values for curve relationships but I just don't get it. | |
# https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Geometry_RegionContainment.htm | |
from Rhino.Geometry import * | |
from Rhino.RhinoDoc import ActiveDoc as rhdoc | |
tol = rhdoc.ModelAbsoluteTolerance | |
ids = range(len(crvs)) | |
# initialize with dictionary of sets containing its own key | |
# i.e all curves in separate clusters | |
clusters = {i: set([i]) for i in ids} | |
rtree = RTree() | |
for i, crv in enumerate(crvs): | |
# populate the RTree with bounding boxes | |
rtree.Insert(crv.GetBoundingBox(True), i) | |
def check_containment(crvA, crvB): | |
# checks if either A contains B or B contains A | |
# relatively expensive, so further optimizations can be made here eg. for polylines | |
rg = Curve.PlanarClosedCurveRelationship(crvA, crvB, Plane.WorldXY, tol) | |
return (rg in (RegionContainment.AInsideB, RegionContainment.BInsideA)) | |
def callback(sender, e): | |
a, b = e.Id, e.IdB | |
if a == b: | |
return | |
if b in clusters[a] or a in clusters[b]: | |
return | |
if check_containment(crvs[a], crvs[b]): | |
clusters[a].add(b) | |
clusters[b].add(a) | |
RTree.SearchOverlaps(rtree, rtree, 0.01, callback) # O(n) | |
# iterate through the clusters from the highest to lowest index | |
for i in reversed(ids): | |
# still O(n) despite nested for loop, because inner loop is ~O(1) | |
for j in list(clusters[i]): # create new list to avoid changing the iterable | |
# merge with sets of a greater index | |
if j > i: | |
try: | |
clusters[i].update(clusters.pop(j)) | |
except KeyError: # j has already been popped | |
pass | |
mapping = [0] * len(crvs) | |
for k, vals in clusters.items(): | |
for v in vals: | |
mapping[v] = k |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment