I’m trying to create a script where I do the following steps:
1 - Create a model line/curve;
2 - Place points at a given interval in that line;
3 - Place points “relative to surface” in a toposurface where those points were created.
I got to the place where I can subdivide the line and place the points at the desired interval, but can’t find a node to place the points in the toposurface.
When you say “relative to surface” I assume you mean projected downward onto the topography. Is that correct?
There has been some recent development going into topography and toposurfaces recently but I’m afraid I don’t know what all has been released at this point. It’s worth checking for some packages though.
However, that’s probably unnecessary for this case as you can use ProjectInputOnto to easily project the points onto the surface below.
I thought only selecting the toposurface would be enough, but apparently it doesn’t recognize it as a surface, but as something else. Do I need nodes to convert it to the expected argument types?
Get the point you wish to project and translate it by an absurd elevation on the inverse Z axis.
Use Mesh.Project to pull the point onto the topography.
Conversion can be tough (Quick and easy to do with a Python node if you know Python, there is a good node in the Springs package too if memory serves if not).
Full outlines are harder as you lose intermediate points on the shape (where the triangle edges of the topography cross the shape). If that is what you’re after look at converting an extrication of the profile to a toolkit mesh as well and try intersecting the two.
The Dynamo graph that powers this is taking samples along the roadway centerlines in a 1M grid along their width but at a flat elevation of -5000. It then projects them up onto the topography, used the projected points to create a new mesh, and finally sets up the display where the color indicates compliant slope vs non-compliant slope.
I ran out of time to try and solve this, but was able to project the points on the surface. From this to interact with the topography, still didn’t happen. When possible, I’ll get to it again and see what happens.
If it works, I’ll try to make this work for toposolids as well.
This might help for anything which you can pull in as a Dynamo mesh:
########################################
############## Properties ##############
########################################
__author__ = 'Jacob Small'
__version__ = '0.1.0'
__description__ = "Project a curve onto a Dynamo mesh"
__DynamoBuilds__ = "2.18"
__ReleaseNotes__ = "not thuroughly tested - test completely before implementing in production"
__Dependancies__ = "none"
__Copyright__ = "2024, Autodesk Inc."
__license__ = "Apache 3.0"
########################################
### Configure the Python environment ###
########################################
### standard imports ###
import clr #add the CLR (common language runtime) class to the Python environment so we can work with .net libraries
### basic Dynamo imports ###
clr.AddReference('ProtoGeometry') #add the Dynamo geometry library to the CLR
from Autodesk.DesignScript import Geometry as DG #add the Dynamo geometry class using the alias DG, to ensure no overlap between class calls in Revit or Dynamo
########################################
######### Inputs and variables #########
########################################
mesh = IN[0] #the terrain mesh
baseCurve = IN[1] #the curve to project
edges = [] #empty list to hold the projected segements
########################################
###### get points and indexgroups ######
########################################
pnts = mesh.VertexPositions #get the points from the terrain
indexGroups = mesh.FaceIndices #get the index groups from the terrain
########################################
############ get base shape ############
########################################
domain = DG.BoundingBox.ByGeometry(pnts) #get the bounding box fo the mesh points
base = baseCurve.Extrude(domain.MaxPoint.Z) #extrude the domain to the height of the bounding box
########################################
### intersect the base with the mesh ###
########################################
for indexGroup in indexGroups: #for each index group
tri = [pnts[i] for i in [indexGroup.A, indexGroup.B, indexGroup.C]] #get the points
tri = DG.Polygon.ByPoints(tri).Patch() #patch a polygon built from the points
if tri.DoesIntersect(base): #if the patched surface intersects the curve
[edges.append(i) for i in tri.Intersect(base)] #append the resulting intersections between the base and the triangle
########################################
##### Return the results to Dynamo #####
########################################
OUT = DG.PolyCurve.ByJoinedCurves(edges) #build a polycurve from the intersected curves