Text content from Lower to Upper

@csanchez try this Python script. You will need to use the Civil 3D Toolkit to feed in a list of object handles, like this:

import sys
import clr

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

# 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 *

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

adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor

 # Add DesignScript references
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Enable Python support and load DesignScript library
from System.Collections.Generic import Dictionary

def get_text_props(handles):
	
	textProps = []
	obj=[]
	keys = ["Contents","Horizontal mode","Vertical mode","Height","Rotation","Width factor","Obliquing","Alignment point","Insertion point","Upside down","Backward"]
	errorReport = None
	
	if not isinstance(handles,list):
		handles = [handles]
	
	global adoc
	
	with adoc.LockDocument():
		with adoc.Database as db:
			with db.TransactionManager.StartTransaction() as t:
				for handle in handles:
					oid=(db.GetObjectId(False,Handle(int(handle,16)),0))
					obj.append(t.GetObject(oid, OpenMode.ForRead))					
					# Create list of properties for each DBtext
					for i in obj:
						val=[]
						try:
							if isinstance(i, DBText):
								val.append(i.TextString)
								
								#Remove "Text" from beginning of text alignment modes
								hMode=str(i.HorizontalMode)
								vMode=str(i.VerticalMode)
								hMode_trim=hMode.Replace("Text","")
								vMode_trim=vMode.Replace("Text","")
								val.append(hMode_trim)
								val.append(vMode_trim)
								
								val.append(i.Height)
								val.append(i.Rotation)
								val.append(i.WidthFactor)
								val.append(i.Oblique)
								
								# Create alignment point
								alignX=i.AlignmentPoint.X
								alignY=i.AlignmentPoint.Y
								alignZ=i.AlignmentPoint.Z
								alignPt=Point.ByCoordinates(alignX,alignY,alignZ)
								val.append(alignPt)
								
								#Create insertion point
								insX=i.Position.X
								insY=i.Position.Y
								insZ=i.Position.Z
								insPt=Point.ByCoordinates(insX,insY,insZ)
								val.append(insPt)
								
								val.append(i.IsMirroredInY)
								val.append(i.IsMirroredInX)				
						# Error handling
						except:
							import traceback
							errorReport = traceback.format_exc()	
					d = {k:v for k,v in zip(keys,val)}
					dict = Dictionary[str,object](d)
					textProps.append(dict)					
				t.Commit()			
	if errorReport == None:
		return textProps
	else:
		return errorReport
	
OUT = get_text_props(IN[0])

Credit to @Kulkul for the initial part of the code here:

4 Likes

Good Job :+1: @mzjensen

You can also collect all text notes in one python snippet:

import sys
import clr

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

# 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 *

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

adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor

 # Add DesignScript references
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Enable Python support and load DesignScript library
from System.Collections.Generic import Dictionary

def get_text_props():
	
	textProps = []
	obj=[]
	keys = ["Contents","Horizontal mode","Vertical mode","Height","Rotation","Width factor","Obliquing","Alignment point","Insertion point","Upside down","Backward"]
	errorReport = None
	
	handles = []
	global adoc
	
	with adoc.LockDocument():
		with adoc.Database as db:
			with db.TransactionManager.StartTransaction() as t:
				bt = t.GetObject(db.BlockTableId, OpenMode.ForWrite)
				btr = t.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite)
				for oid in btr:
					bl = t.GetObject(oid, OpenMode.ForRead)
					if isinstance(bl, DBText):
						handles.append(str(bl.Handle))
				for h in handles:
					oid=(db.GetObjectId(False,Handle(int(h,16)),0))
					obj.append(t.GetObject(oid, OpenMode.ForRead))					
				# Create list of properties for each DBtext
				for i in obj:
					val=[]
					try:
						
						val.append(i.TextString)
						
						#Remove "Text" from beginning of text alignment modes
						hMode=str(i.HorizontalMode)
						vMode=str(i.VerticalMode)
						hMode_trim=hMode.Replace("Text","")
						vMode_trim=vMode.Replace("Text","")
						val.append(hMode_trim)
						val.append(vMode_trim)
						
						val.append(i.Height)
						val.append(i.Rotation)
						val.append(i.WidthFactor)
						val.append(i.Oblique)
						
						# Create alignment point
						alignX=i.AlignmentPoint.X
						alignY=i.AlignmentPoint.Y
						alignZ=i.AlignmentPoint.Z
						alignPt=Point.ByCoordinates(alignX,alignY,alignZ)
						val.append(alignPt)
						
						#Create insertion point
						insX=i.Position.X
						insY=i.Position.Y
						insZ=i.Position.Z
						insPt=Point.ByCoordinates(insX,insY,insZ)
						val.append(insPt)
						
						val.append(i.IsMirroredInY)
						val.append(i.IsMirroredInX)				
					# Error handling
					except:
						import traceback
						errorReport = traceback.format_exc()	
					d = {k:v for k,v in zip(keys,val)}
					dict = Dictionary[str,object](d)
					textProps.append(dict)		
				
				t.Commit()			
	if errorReport == None:
		return textProps
	else:
		return errorReport
	
OUT = get_text_props()
2 Likes

@Kulkul thanks!

That is actually the approach I originally used because of what I saw in your example. But I changed it to provide the option to use specific texts as the input. I was thinking that sometimes you don’t want to automatically select every text in the block table record. For example, maybe only texts on a specific layer.

@Kulkul I was also trying to find a way to actually set the text contents. That is the original goal of this post - my script only queries text properties. Do you have any thoughts?

That’s easy one. You can just add:

if isinstance(bl, DBText) and bl.Layer==LN:

1 Like

That’s very easy one also:

i.TextString.upper()

2 Likes

Great! There you go @csanchez, you have a few options to work with now. Here is a simplified version if you don’t care to have the dictionary output.

import sys
import clr

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

# 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 *

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

adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor

def text_to_upper(handles):
	
	text=[]
	obj=[]
	errorReport = None
	
	if not isinstance(handles,list):
		handles = [handles]
	
	global adoc
	
	with adoc.LockDocument():
		with adoc.Database as db:
			with db.TransactionManager.StartTransaction() as t:
				for handle in handles:
					oid=(db.GetObjectId(False,Handle(int(handle,16)),0))
					obj=t.GetObject(oid, OpenMode.ForWrite)					
					try:
						if isinstance(obj, DBText):
							newText=obj.TextString.upper()
							obj.TextString=newText
							text.append(newText)							
					# Error handling
					except:
						import traceback
						errorReport = traceback.format_exc()						
				t.Commit()			
	if errorReport == None:
		return text
	else:
		return errorReport
	
OUT = text_to_upper(IN[0])
2 Likes

Thank you guys for the help. i created the python script and copied and pasted the code but nothing changed i CAD and i see this warning. I a doing something wrong? i am not familiar with python for cad… thanks.

You need to input a list of object handles like the picture in this above post:

Thank you, it works like a charm. I want to learn Python for Dynamo but i don’t see a good place to find a step by step learning. DO you know where i can find good tutorials?

1 Like

There isn’t really a consolidated resource for specific “Python for Civil 3D” documentation. You’ll have to just dive in and learn from examples on this site in combination with the API documentation for AutoCAD/Civil 3D.

Thank you very much guys.

This can help a little https://procadblog.files.wordpress.com/2017/10/pro-cad-civil-3d-2018-c-sharp-net-cheat-sheet.pdf

6 Likes

Some more potentially useful info:

1 Like

Sorry to ask but how do I use the Python script in my Dynamo graph? This script allows me to select what layer to take the Text from? Thank you so much in advance.

@raul.07.11

https://primer.dynamobim.org/10_Custom-Nodes/10-4_Python.html

Thanks very much!

Hi Zachri, I have literally copied and pasted this script into my python node in dynamo for civil 3D, and the program throws me a series of error messages.

This is the version of Dynamo that I have, and I also have the DynamoIronPython2.7 V1.0.0 package installed.
image

Hi @henrybajana,

Did you get this figured out?

Not yet