Use Dynamo to create and manipulate Autocad / Civil 3D layers

Would anybody know how to create a layer in Autocad / Civil 3D, and set name and color, using Python in Dynamo?

1 Like

@jacob.small

In Dynamo for Civil 3D 2020 you can feed any string value into the “Layer” input of most nodes and it will make a new layer with that name. I have not seen anyone set layer colors though. Object color is doable via OOTB nodes though.

I know that. But setting layer color is essential in my case. I did not find any OOTB nodes to do that, so i am eager to try some AutoCAD dotNET API stuff through Dynamo and Python. But cant find a good reference for this :slight_smile:

Hi try this Link to get an idea of what is the code to create a Layer.
Attached an implementation with Python in Dynamo for Civil 3D.CreateLayerByNameColor.dyn (8.7 KB)

6 Likes

Thanks for helping out, @Paolo_Emilio_Serra1. Will check this out.

2 Likes

Hi @Paolo_Emilio_Serra1 thanks for posting the CreateLayerByNameColor script - this is super helpful! I am trying to do the same thing but instead set the color by ACI. I was reading that “ColorMethod.ByAci” can be used for this task but am getting an error in my python code when I write it this way. Do you have any suggestions?
image

"""
Copyright 2019 Autodesk, Inc. All rights reserved.

This file is part of the Civil 3D Python Module.

"""
__author__ = 'Paolo Emilio Serra - paolo.serra@autodesk.com'
__modifiedby__ = 'Deivid Steffens - deividsteffens@msn.com'
__copyright__ = '2020'
__version__ = '1.0.0'

import clr

# Add Assemblies for AutoCAD and Civil 3D APIs
clr.AddReference('acmgd')
clr.AddReference('acdbmgd')
clr.AddReference('accoremgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')
clr.AddReference('AeccPressurePipesMgd')
clr.AddReference('acdbmgdbrep')
clr.AddReference('System.Windows.Forms')

# Add standard Python references
import sys
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')
import os
import math

# Add references to manage arrays, collections and interact with the user
from System import *
from System.IO import *
from System.Collections.Specialized import *
from System.Windows.Forms import MessageBox

# Create an alias to the Autodesk.AutoCAD.ApplicationServices.Application class
import Autodesk.AutoCAD.ApplicationServices.Application as acapp

# 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 *
from Autodesk.AutoCAD.Colors import Color
from Autodesk.AutoCAD.Colors import ColorMethod
# Import references for PropertySets
from Autodesk.Aec.PropertyData import *
from Autodesk.Aec.PropertyData.DatabaseServices import *

# Import references for Civil 3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

adoc = acapp.DocumentManager.MdiActiveDocument
ed = adoc.Editor

# Example function
def create_layer(name, index):

	indx = int(index)
	
	# Fail gracefully
	if not isinstance(name, str) or len(name) == 0:
		raise Exception('The name is not a valid string')
	if not isinstance(indx, int) or indx < 0 or indx > 255:
		raise Exception('The index component is not a valid integer')
	
	# replace invalid characters in the name
	name = name.replace(':', '_').replace(';', '_').replace(',', '_')
		
	global adoc
	result = False

	with adoc.LockDocument():
		with adoc.Database as db:
			with db.TransactionManager.StartTransaction() as t:
				# Get the Layer Table Object
				lt = t.GetObject(db.LayerTableId, OpenMode.ForRead)
				# Check if the layer already exists
				if not lt.Has(name):
					with LayerTableRecord() as ltr:
						ltr = LayerTableRecord()
						ltr.Name = name
						ltr.Color = Color.FromColorIndex(ColorMethod.ByAci,indx)
						lt.UpgradeOpen()
						lt.Add(ltr)
						lt.DowngradeOpen()
						t.AddNewlyCreatedDBObject(ltr, True)
				else:
					ltr = t.GetObject(lt[name], OpenMode.ForWrite)
				# Set the color
				if ltr is not None:
					ltr.Color = Color.FromColorIndex(ColorMethod.ByAci,indx)
				
				result = True
				t.Commit()
		
	return result
	

if IN[0] == None or IN[1] == None:
	OUT = create_layer.__doc__
else:
	OUT = create_layer(IN[0], IN[1])
5 Likes

with this script I get error: Autodesk.AutoCAD.ApplicationServices is not a package , line 27
import Autodesk.AutoCAD.ApplicationServices.Application as acapp

I thought that including line-type property while creating the new layer would be “straight-forward”. Looks like the line-type project is LinetypeObjectId. I managed to access the line-type table object, but havent figured out how to transfer the ObjectId of an existing line-type table record.