I have been testing the various nodes available with a view to being able to sample surface elevations by either projecting points or polycurves or lines to allow for further computational design workflows.
Within the dynamo environment by creating dynamo surface (from a C3D TinSurface) and projecting constructed dynamo polycurves or lines, works but can be slow depending on complexity of surface - it would be great to have a way to save the generated 3d polylines, i guess i could save out points to excel after initial run, to allow for faster workflow from that stage onward.
I only managed to get this working by going creating my construction lines above the surface and then with my C3D TinSurface I used TinSurfaceExtensions.GetMesh then using ‘Springs Nodes’ Mesh.ToPolysurface. then use surface.ProjectInputOnto. It can be very slow, and does not always work depending on complexity of surface.
I guess An alternative would be to just use C3D tools to sample surface based on polylines and then bring these into dynamo for processing.
test _Surface_Points_Levels.dyn (77.3 KB)I thought about automating this to alllow for more flexibility , make it more dynamic, but not many python examples of this, so I tried to convert this c# code into python:
https://civilizeddevelopment.typepad.com/civilized-development/surfaces/
It needs to be provided with points from the polylines or lines (i only have start and end points in this test code, will add more when i get it working), here is python script that I am having trouble with:
# Load the Python Standard and DesignScript Libraries
import sys
import clr
# Add Assemblies for AutoCAD and Civil3D
clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')
# Import references from AutoCAD
from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.EditorInput import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *
# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *
# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN
surf_name = IN[0]
pline_start = IN[1]
pline_end = IN[2]
samplepoints = []
adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor
with adoc.LockDocument():
with adoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
bt = t.GetObject(db.BlockTableId, OpenMode.ForWrite)
btr = t.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite)
for oid in btr:
obj = t.GetObject(oid, OpenMode.ForRead)
if isinstance(obj, TinSurface):
if obj.Name == surf_name:
surf =oid
if surf is not None:
break
for pls in pline_start:
for ple in pline_end:
acPoly3d = Polyline3d()
btr.AppendEntity(acPoly3d)
t.AddNewlyCreatedDBObject(acPoly3d, True)
acPts3dPoly = Point3dCollection()
acPts3dPoly.Add(Point3d(pls[0],pls[1],pls[2]))
acPts3dPoly.Add(Point3d(ple[0],ple[1],ple[2]))
for i in list(range(0,acPts3dPoly.Count)):
acPolVer3d = PolylineVertex3d(acPts3dPoly.Item[i])
acPoly3d.AppendVertex(acPolVer3d)
t.AddNewlyCreatedDBObject(acPolVer3d, True)
cid = acPoly3d.ObjectId
samplepoints.append(surf.SampleElevations(cid))
# Commit before end transaction
t.Commit()
pass
# Assign your output to the OUT variable.
OUT = samplepoints
Anyway - cant figure out the correct way to get items in the Points3dCollection() is there a more dynamic / pythonic way of doing this, i thought I had it with above code but not working, help OR appreciate OTHER ideas for streamlining this kind of workflow appreciated: