# AutoCAD Hatch Boundary by Layer

**URL:** <https://forum.dynamobim.com/t/autocad-hatch-boundary-by-layer/38404>\
**Category:** Uncategorized\
**Created:** [July 17, 2019, 8:43pm UTC](https://forum.dynamobim.com/t/autocad-hatch-boundary-by-layer/38404 "2019-07-17T20:43:06Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mark.Ackerley](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/mark.ackerley/32/79310_2.png) [@Mark.Ackerley](https://forum.dynamobim.com/u/Mark.Ackerley)\
**Post date:** [July 17, 2019, 8:43pm UTC](https://forum.dynamobim.com/t/autocad-hatch-boundary-by-layer/38404/1 "2019-07-17T20:43:06Z")

</div>

So… it’s been one of those days…

All I want is to grab the hatch in a dwg, grab it’s outline and extrude them.

Seems simple…?! Hmmm…

I’ve been trawling the awesome LinkDwg package @Koz_Jono_Yeoh (I know biMorph also has some excellent work here @Thomas_Mahon ).

I can get the hatches, but they are not associated so the GetLoopAt method for comObjects fails.

So I need to stay within AutoCAD and use something like “-HatchEdit” or “HATCHGENERATEBOUNDARY” unfortunately this means using LISP (woop another coding language) and they all get dumped on the active layer, so I don’t know whether it’s to be extruded the height of a building or the height of a kerb.

[https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/recreate-multiple-hatch-boundaries-as-polygons-each-in-the-layer/td-p/3275725](https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/recreate-multiple-hatch-boundaries-as-polygons-each-in-the-layer/td-p/3275725)

This would be fine if I had the same number of objects as boundaries, unfortunately that doesn’t happen… So I need to iterate through each object, grab it’s layer and get any boundaries and dump that in it’s own list.

Unfortunately I haven’t been able to loop inside AutoCAD, I can only get all the hatches and extract all of them with PickfirstSelectionSet. I need to pick each hatch in turn, but I can’t think of a workflow for that ☹

Any assistance greatly appreciated!

Thanks,

Mark

[CAD Hatch dwg outlines.dyn](https://forum.dynamobim.com/uploads/short-url/1sbfN4EzzWA5WsDQ91clmvCVXTH.dyn) (16.0 KB)

 ![Capture](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/2/5/257adec4436fcb8cc3453b73900754a403feb50f.png)

```
#LinkDWG Core DYF by Koz Jono YEOH
#kozmosovia@hotmail.com
#Copyright(C) 1994-2018 KozMos Inc.
#Copyright(C) 2011-2018 Neila Heaven Networks
#Cioyright(c) 2017-2018 Tachyon Intelligent Design Institute

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

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager

def _GetOrCreateAutoCAD(progid):
    try:
        from System.Runtime.InteropServices import Marshal
        return Marshal.GetActiveObject(progid)
    except:
        try:
            from System import Type, Activator
            t = Type.GetTypeFromProgID(progid)
            return Activator.CreateInstance(t)
        except: pass

def _ValidFile(filename):
    try:
        with open(filename) as f:
            return True
    except IOError:
        return False

UIDOC = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
DWG = UnwrapElement(IN[0])
VIS = IN[1]
RTN = [None]

if DWG != None:
	try:
		LNK=UIDOC.Document.GetElement(DWG.GetTypeId())
		PATH=ModelPathUtils.ConvertModelPathToUserVisiblePath(LNK.GetExternalFileReference().GetAbsolutePath())
		if _ValidFile(PATH):
			try:
				CAD=_GetOrCreateAutoCAD("Autocad.Application")
				CAD.Visible=VIS
				DOC=CAD.Documents.Open(PATH)
				DOC.SendCommand("(SSGET\"_x\"'((-4 . \"<OR\")(0 . \"*TEXT,*HATCH\")(-4 . \"<AND\")(0 . \"INSERT\")(66 . 1)(-4 . \"AND>\")(-4 . \"OR>\"))) ")
				DOC.SendCommand("SELECT (SSGET\"_p\") ")
				DOC.SendCommand("HATCHGENERATEBOUNDARY ")
				SEL=DOC.PickfirstSelectionSet
				RRR=[]
				for obj in SEL:
					if obj.ObjectName == "AcDbHatch":
						RRR.append([obj, obj.Layer])
				RTN=RRR #doc
			except: pass
	except: pass

OUT = RTN
```

---

<div class="post-metadata">

**Author:** ![jacob.small](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/jacob.small/32/161030_2.png) [@jacob.small](https://forum.dynamobim.com/u/jacob.small)\
**Post date:** [July 18, 2019, 1:20am UTC](https://forum.dynamobim.com/t/autocad-hatch-boundary-by-layer/38404/2 "2019-07-18T01:20:35Z")

</div>

Got a dwg you can share? Is using Civil3D 2020 (and the included Dynamo integration) an option?

---

<div class="post-metadata">

**Author:** ![Mark.Ackerley](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/mark.ackerley/32/79310_2.png) [@Mark.Ackerley](https://forum.dynamobim.com/u/Mark.Ackerley)\
**Post date:** [July 18, 2019, 10:40am UTC](https://forum.dynamobim.com/t/autocad-hatch-boundary-by-layer/38404/3 "2019-07-18T10:40:01Z")

</div>

Hey Jacob,

Sure…

[test.rvt](https://forum.dynamobim.com/uploads/short-url/dfu7jDyfEXRyjp5bz1M4DAw5omO.rvt) (1.3 MB) [CAD Hatch dwg outlines.dyn](https://forum.dynamobim.com/uploads/short-url/cCPixglwhHQjIwVmgs2anXBw0Wx.dyn) (19.8 KB) [test.dwg](https://forum.dynamobim.com/uploads/short-url/yXvWANR3xRH1JjNXbJhORL1xo0Z.dwg) (41.8 KB)

If we can get something working somehow that would be an improvement!

More links I’m looking at:

[https://through-the-interface.typepad.com/through\_the\_interface/2006/08/calling\_command.html](https://through-the-interface.typepad.com/through_the_interface/2006/08/calling_command.html) @keanw R10?! seriously?! 😃

> **[SendCommand Method (ActiveX) | Search | Autodesk Knowledge Network](https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-E13A580D-04CA-46C1-B807-95BB461A0A57-htm.html)**
>
> Sends a command string from a VB or VBA application to the document for processing. Supported platforms: Windows only Signature VBA: object.SendCommand Command object Type: Document The object this method applies to. Command Access: Input-only Type:...

> **[HatchObjectType Property (ActiveX) | Search | Autodesk Knowledge Network](https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-BBDF246E-8F3E-45D8-9906-2A6970322235-htm.html)**
>
> Specifies the type of the hatch, classic or gradient. Supported platforms: Windows only Signature VBA: object.HatchObjectType object Type: Hatch The object this property applies to. Property Value Read-only: No Type: AcHatchObjectType enum...

---

<div class="post-metadata">

**Author:** ![Mark.Ackerley](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/mark.ackerley/32/79310_2.png) [@Mark.Ackerley](https://forum.dynamobim.com/u/Mark.Ackerley)\
**Post date:** [July 19, 2019, 2:36pm UTC](https://forum.dynamobim.com/t/autocad-hatch-boundary-by-layer/38404/4 "2019-07-19T14:36:53Z")

</div>

So I got there eventually, the code is butt ugly, it would be great if anyone could help tidy it…

Cheers,

Mark

```
#LinkDWG Core DYF by Koz Jono YEOH
#kozmosovia@hotmail.com
#Copyright(C) 1994-2018 KozMos Inc.
#Copyright(C) 2011-2018 Neila Heaven Networks
#Cioyright(c) 2017-2018 Tachyon Intelligent Design Institute

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

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager

def _GetOrCreateAutoCAD(progid):
    try:
        from System.Runtime.InteropServices import Marshal
        return Marshal.GetActiveObject(progid)
    except:
        try:
            from System import Type, Activator
            t = Type.GetTypeFromProgID(progid)
            return Activator.CreateInstance(t)
        except: pass

def _ValidFile(filename):
    try:
        with open(filename) as f:
            return True
    except IOError:
        return False

UIDOC = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
DWG = UnwrapElement(IN[0])
VIS = IN[1]
RTN = []

if DWG != None:
	LNK=UIDOC.Document.GetElement(DWG.GetTypeId())
	PATH=ModelPathUtils.ConvertModelPathToUserVisiblePath(LNK.GetExternalFileReference().GetAbsolutePath())
	if _ValidFile(PATH):
		RRR = []
		CAD=_GetOrCreateAutoCAD("Autocad.Application")
		CAD.Visible=VIS
		DOC=CAD.Documents.Open(PATH)

		#if i could get select previous to work after I've exploded and joined the regions I wouldn't need any of this next part
		
		#we will eventually make polylines from the regions, so we don't want any in there right now
		#to ensure we can delete polylines, we need at least one in the file... should use an if not but this seems faster not knowing the language!		
		DOC.SendCommand("_pline 0 0,1 ")	
		#lisp! select POLYLINES
		DOC.SendCommand("(ssget \"_X\" \'((0 . \"*POLYLINE\"))) ")	
		
		#delete any polylines in the file, because I can't find a way of selecting them after the join command... not ideal		
		#this selects the section set (SSGET) we just made
		DOC.SendCommand("SELECT (SSGET\"_p\") ")		
		DOC.SendCommand("DELETE ")

		#lisp! select hatch and create search set
		DOC.SendCommand("(SSGET\"_x\"'((-4 . \"<OR\")(0 . \"HATCH\")(-4 . \"<AND\")(0 . \"INSERT\")(66 . 1)(-4 . \"AND>\")(-4 . \"OR>\"))) ")
		#this selects the section set (SSGET) we just made
		DOC.SendCommand("SELECT (SSGET\"_p\") ")
		
		#make the outlines of the hatch
		#in python \" means python will not include the \, but it will include the ", without thinking that it's the termination of the quote.
		#find replace is handy for converting from lisp to the version in python!
		#\"p\" tells it to be a polyline
		DOC.SendCommand("(setq SSET (ssget))(setq CNT -1)(while (setq OBJ (ssname SSET (setq CNT (1+ CNT))))(setvar 'clayer (cdr (assoc 8 (entget OBJ))))(command \"-hatchedit\" OBJ \"b\" \"p\" \"y\"))(setvar \"cmdecho\" OLDCE) ")

		#select all polylines, which are now the new polylines.
		DOC.SendCommand("(ssget \"_X\" \'((0 . \"*POLYLINE\"))) ")	
		#this is a new section set (SSGET) we just made
		DOC.SendCommand("SELECT (SSGET\"_p\") ")	
		
		#this gets the active selection		
		SEL=DOC.PickfirstSelectionSet
		for regionLine in SEL:
			RRR.append([regionLine.Layer, regionLine])
		RTN.append(RRR)	

OUT = RTN
```

---

<div class="post-metadata">

**Author:** ![jasper.dekoster](https://avatars.discourse-cdn.com/v4/letter/j/c57346/32.png) [@jasper.dekoster](https://forum.dynamobim.com/u/jasper.dekoster)\
**Post date:** [October 5, 2022, 7:35am UTC](https://forum.dynamobim.com/t/autocad-hatch-boundary-by-layer/38404/5 "2022-10-05T07:35:06Z")

</div>

This script sadly doesn’t work anymore in C3D 2022 because Dynamo stepped away from Iron Python. Is there still a way to make this script work?

---

<div class="post-metadata">

**Author:** ![kovacsv](https://avatars.discourse-cdn.com/v4/letter/k/f6c823/32.png) [@kovacsv](https://forum.dynamobim.com/u/kovacsv)\
**Post date:** [October 5, 2022, 7:42am UTC](https://forum.dynamobim.com/t/autocad-hatch-boundary-by-layer/38404/6 "2022-10-05T07:42:04Z")

</div>

You can still use IronPython via package. If installed you can change the PythonScript node engine version.  
 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/1/c/1ccee5cb419efe976a9199eefd60103cd2b5bd03.png)  
 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/a/6/a6c09cdc55598807e362741d93d0ba369a2a5511.png)

---

<div class="post-metadata">

**Author:** ![hanywillim](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/hanywillim/32/155832_2.png) [@hanywillim](https://forum.dynamobim.com/u/hanywillim)\
**Post date:** [February 26, 2024, 1:43pm UTC](https://forum.dynamobim.com/t/autocad-hatch-boundary-by-layer/38404/7 "2024-02-26T13:43:34Z")

</div>

Bro, how can i use this code with CAD 2024 Environment,  
because it seems that the function:  
def \_GetOrCreateAutoCAD(progid)  
does not work with cad 2024

thanks in adnvance
