How to set Civil 3D Drawing Units and Zones in all dwg files of a path and then join all drawings into one dwg by separating them into blocks using Dynamo

Here’s an example to get you started. This will process an entire folder of DWGs and update the coordinate system code and drawing units for each file. You’ll need to have a DWG open so that you can run it through Dynamo or Dynamo Player, but the other files are not actually opened, which makes it a lot faster. The code is adapted from @Paolo_Emilio_Serra1’s example below.

If you haven’t already, it would be good to read up on element bindings/trace data before you continue working on this workflow. The short story is that you’ll probably have to accomplish pretty much all of the tasks via Python, although you could try to utilize some of the built-in nodes (or even the Civil 3D Toolkit nodes) within your code.

UpdateDrawingSettings1

# Load the Python Standard and DesignScript Libraries
import clr
import System
import os

# Add Assemblies for AutoCAD and Civil3D
clr.AddReference('AcMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AeccDbMgd')

# Import references from AutoCAD
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.DatabaseServices import *

# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *
from Autodesk.Civil.Settings import *

def set_drawing_units(path, units, code):
	"""
	Loads a DWG file as a side database.
	Gets the drawings settings for coordinate system code and drawing units.
	Updates the coordinate system code and units if necessary.
	Saves the changes.
	
	@path: A path to a Civil 3D DWG file
	@units: A string for the desired document units, either "Feet" or "Meters"
	@code: A string for the desired coordinate system code
	@returns: True if successful, otherwise False
	"""

	# Check for null inputs
	if path is None or units is None or code is None:
		return False
		
	# Initialize variables	
	adoc = Application.DocumentManager.MdiActiveDocument
	output = True
	
	with adoc.LockDocument():
		# Load DWG as side database
		db = Database(False, True)
		db.ReadDwgFile(path, System.IO.FileShare.ReadWrite, True, "")
		if db is None:
			return False
		with db.TransactionManager.StartTransaction() as t:
			cdoc = CivilDocument.GetCivilDocument(db)
			# Get drawing settings
			settings = cdoc.Settings.DrawingSettings.UnitZoneSettings
			drawingCode = settings.CoordinateSystemCode
			drawingUnits = settings.DrawingUnits.ToString()
			# Update coordinate system code and units if different
			if drawingCode != code: # 
				settings.CoordinateSystemCode = code  
			if drawingUnits != units:
				settings.DrawingUnits = System.Enum.Parse(DrawingUnitType, units)	            	
			t.Commit()	            
		# Save changes
		db.SaveAs(db.Filename, DwgVersion.Current)
	return output

def main(folder, units, code):
	"""
	Credit to original author, Paolo Emilio Serra.
	Gets all the DWGs in a folder path recursively.
	Loads each file as a side database, updates drawing settings, and saves the changes.
	
	@folder: The path to folder containing Civil 3D DWGs
	@units: A string for the desired document units, either "Feet" or "Meters"
	@code: A string for the desired coordinate system code
	@returns: A Dictionary of successes and failures
	"""
	# Check for null inputs
	if folder is None or units is None or code is None:
		return None

	# Initialize variables
	docs = []
	adoc =  Application.DocumentManager.MdiActiveDocument
	output = {}
	output['Success'] = []
	output['Failure'] = []

	# Get documents
	for dirpath, dnames, fnames in os.walk(folder):
		for f in fnames:
			if f.endswith('.dwg'):
				docs.append(os.path.join(dirpath, f))
	
	# Loop through each document and update settings
	for doc in docs:
		result = set_drawing_units(doc, units, code)
		if result:
			output.setdefault('Success', []).append(doc)
		else:
			output.setdefault('Failure', []).append(doc)

	Application.DocumentManager.CurrentDocument = adoc
	
	return output

OUT = main(IN[0], IN[1], IN[2])
5 Likes