Porting Custom (Python) Node from Revit to Civil 3D

Hi everyone,

I have been working with the SteamNodes “PointCloud.GetPointsFromBoxSelection” node in Revit 2020 and it works great! :smiley: However, our models (and also corresponding Dynamo scripts) are preferably in Civil 3D, mainly because that eliminates the intermediate step of having to use Revit together with Dynamo and finding some creative solutions for exporting PolyLines.

So I was wondering if anyone had looked into how Civil 3D handles Point Clouds. And if not, where would be the best place for me to start looking. :smiley:

The Node

image

Nested Python Code 1
#python nodes in dynamo 1.2
####BETA VERSION#####
#proposed by Julien Benoit @jbenoit44 
#http://aecuandme.wordpress.com/
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)
# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from System.Collections.Generic import *
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.PointClouds import *
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument


planes=[]
for i in IN[1]:
	planes.append(UnwrapElement(i).ToPlane())
Iplanes=List[Autodesk.Revit.DB.Plane](planes)


pcf=PointCloudFilterFactory.CreateMultiPlaneFilter(planes)

averageDistance = IN[2]
numberOfPoints= IN[3]

points = UnwrapElement(IN[0]).GetPoints(pcf, averageDistance, numberOfPoints)
elements=[]
for p in points:
	X=p.X
	Y=p.Y
	Z=p.Z
	elements.append(Point.Create(XYZ(X,Y,Z)).ToProtoType(False))


OUT = elements
Nested Python Code 2
# Thanks for this code goes to:
# Copyright(c) 2016, Konrad K Sobon
# @arch_laboratory, http://archi-lab.net

# Import Element wrapper extension methods
import clr
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

#The inputs to this node will be stored as a list in the IN variable.
dataEnteringNode = IN

def ProcessList(_func, _list):
    return map( lambda x: ProcessList(_func, x) if type(x)==list else _func(x), _list )

def Unwrap(item):
	return UnwrapElement(item)

def GetTransform(e):
	return e.GetTotalTransform().Origin.ToPoint()
def GetBasisX(e):
	return e.GetTotalTransform().BasisX.ToPoint()
def GetBasisY(e):
	return e.GetTotalTransform().BasisY.ToPoint()
def GetBasisZ(e):
	return e.GetTotalTransform().BasisZ.ToPoint()

if isinstance(IN[0], list):
	elements = ProcessList(Unwrap, IN[0])
else:
	elements = [Unwrap(IN[0])]

try:
	errorReport = None
	output = ProcessList(GetTransform, elements),ProcessList(GetBasisX, elements),ProcessList(GetBasisY, elements),ProcessList(GetBasisZ, elements)
except:
	# if error accurs anywhere in the process catch it
	import traceback
	errorReport = traceback.format_exc()

#Assign your output to the OUT variable
if errorReport == None:
	OUT = output
else:
	OUT = errorReport

Kind regards,
Daan