Dynamo python export polyine and hatch to AutoCad

I didn’t find in Linkdwg a tool to export a polyline to AutoCAD that contains arcs, only polygon to polyline or polycruve to a bunch of separated lines and arcs.
T1.dyn (26.0 KB)


I wanted to get the room boundary to convert to polyline and exported to AutoCAD, if the room boundary has more than one boundary, sort the boundary list in descending order by area to get the outer-loop at index 0 and the inner-loop to contain the rest of the list in order to create hatch in AutoCAD.

The First script to convert boundaries that do not have an arc in it to polygon and leave the rest unchanged.

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# The inputs to this node will be stored as a list in the IN variables.
mine = IN[0]

def cArc(var):
	lArc = []
	for i in var:
		myArc = False
		for x in i:
			typ = str(x.GetType())
			if "Arc" in typ:
				myArc = True
		if myArc != True:
			allPoints = []
			for x in i:
				allPoints.append(x.StartPoint)
				allPoints.append(x.EndPoint)
			myPoly = Polygon.ByPoints(allPoints)
			lArc.append(myPoly)
		else:
			lArc.append(i)
	return lArc
	

# Place your code below this line

# Assign your output to the OUT variable.
OUT = cArc(mine)

The second script takes the boundary with an arc, get the arc start/endpoint and the sweep angle for the Arc than convert it to a bulge value, replace the arc with a line then convert it to a polygon and export it as a polyline to AutoCAD then edit the polyline using the bulge value to create the arc.

# Load the Python Standard and DesignScript Libraries
import sys, clr, System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
from math import tan, radians
from System import Array

# The inputs to this node will be stored as a list in the IN variables.
var = IN[0]
# Place your code below this line
def _con(x1):
	typ = str(x1.GetType())
	if "Polygon" in typ:
		px=[]
		for p0 in x1.Points:
			px.append(p0.X)
			px.append(p0.Y)
			px.append(p0.Z)
		px=Array[float](px)
		vlo=SPACE.AddPolyline(px)
		vlo.Closed=True
	return vlo

# Prepare AutoCAD
CAD = System.Runtime.InteropServices.Marshal.GetActiveObject("Autocad.Application").ActiveDocument

if CAD.ActiveSpace == 1:
	SPACE = CAD.ModelSpace
else:
	SPACE = CAD.PaperSpace

# The rest
allPoly = []

for i in var:
	if "list" in str(type(i)):
		count = []
		ang = []
		for x in range(len(i)):
			if "Arc" in str(i[x].GetType()):
				count.append(x)
		for xx in count:
			sp = i[xx].StartPoint
			ep = i[xx].EndPoint
			# Convert sweeping angle to bulge
			ea = i[xx].SweepAngle
			ea = tan(radians(ea / 4))
			ang.append(ea)
			i[xx] = Line.ByStartPointEndPoint(sp, ep)
		allPoints = []
		for x in i:
			allPoints.append(x.StartPoint)
			allPoints.append(x.EndPoint)
		myPoly = Polygon.ByPoints(allPoints)
		myPoly = _con(myPoly)
		for xx in range(len(count)):
			myPoly.SetBulge(count[xx], ang[xx])
		allPoly.append(myPoly)
	else:
		myPoly = _con(i)
		allPoly.append(myPoly)
# Assign your output to the OUT variable.
OUT = allPoly

The third Script to create hatch using the previously created polyline but unfortunately, this part is not working, I can only create the hatch using the pywin32 library in visual studio code outside of Dynamo but within dynamo I’m unable to import it.

# Load the Python Standard and DesignScript Libraries
import sys, clr, System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
from math import tan, radians
from System import Array

# The inputs to this node will be stored as a list in the IN variables.
var = IN[0]
# Place your code below this line

def myLoop(myObj):
	a = []
	a.append(myObj)
	return a
# Create Hatch
outerLoop = myLoop(allPoly[0])
innerLoop = myLoop(allPoly[1])
hatchObj = SPACE.AddHatch(0, "ANSI31", True)
hatchObj.AppendOuterLoop(outerLoop)
hatchObj.AppendInnerLoop(innerLoop)
hatchObj.Evaluate()
hatchObj.PatternScale = 6

CAD.Application.Update()
# Assign your output to the OUT variable.
OUT = allPoly

Any advice on how to solve that

Hello @gabdelmo

try this

# Load the Python Standard and DesignScript Libraries
import sys, clr, System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
from math import tan, radians
from System import Array
try:
	clr.AddReference('Autodesk.AutoCAD.Interop.Common')
	from Autodesk.AutoCAD.Interop.Common import AcadEntity, AcBooleanType
except:
	stringversion = '2018' #replace by your version if fail
	clr.AddReferenceToFileAndPath('C:/Program Files/Autodesk/AutoCAD {}/Autodesk.AutoCAD.Interop.Common'.format(stringversion))
	from Autodesk.AutoCAD.Interop.Common import AcadEntity, AcBooleanType


# The inputs to this node will be stored as a list in the IN variables.
var = IN[0]
# Place your code below this line
def _con(x1):
	typ = str(x1.GetType())
	if "Polygon" in typ:
		px=[]
		for p0 in x1.Points:
			px.append(p0.X)
			px.append(p0.Y)
			px.append(p0.Z)
		px=Array[float](px)
		vlo=SPACE.AddPolyline(px)
		vlo.Closed=True
	return vlo

def myLoop(myObj):
	a = []
	a.append(myObj)
	return a
# Prepare AutoCAD
CAD = System.Runtime.InteropServices.Marshal.GetActiveObject("Autocad.Application").ActiveDocument


if CAD.ActiveSpace == 1:
	SPACE = CAD.ModelSpace
else:
	SPACE = CAD.PaperSpace

# The rest
allPoly = []

for i in var:
	if "list" in str(type(i)):
		count = []
		ang = []
		for x in range(len(i)):
			if "Arc" in str(i[x].GetType()):
				count.append(x)
		for xx in count:
			sp = i[xx].StartPoint
			ep = i[xx].EndPoint
			# Convert sweeping angle to bulge
			ea = i[xx].SweepAngle
			ea = tan(radians(ea / 4))
			ang.append(ea)
			i[xx] = Line.ByStartPointEndPoint(sp, ep)
		allPoints = []
		for x in i:
			allPoints.append(x.StartPoint)
			allPoints.append(x.EndPoint)
		myPoly = Polygon.ByPoints(allPoints)
		myPoly = _con(myPoly)
		for xx in range(len(count)):
			myPoly.SetBulge(count[xx], ang[xx])
		allPoly.append(myPoly)
	else:
		myPoly = _con(i)
		allPoly.append(myPoly)

# Create Hatch

outerLoop=Array.CreateInstance(AcadEntity,1)
outerLoop[0] = allPoly[0]
innerLoop=Array.CreateInstance(AcadEntity,1)
innerLoop[0] = allPoly[1]


hatchObj = SPACE.AddHatch(0, "ANSI31", True)
hatchObj.AppendOuterLoop(outerLoop)
hatchObj.AppendInnerLoop(innerLoop)
hatchObj.Evaluate()
hatchObj.PatternScale = 1

CAD.Application.Update()
# Assign your output to the OUT variable.
OUT = allPoly, innerLoop
2 Likes

Thanks a lot, I tried it that way and it works.
I really appreciate your help I’m new to this I think I still need to learn a lot more about interacting with different API and how to import and use the right method.

1 Like

3 posts were split to a new topic: Get Hatch Boundary from Autocad