Text content from Lower to Upper

Hi,

I am trying to create a dynamo script to convert all the text content in the cad file to Uppercase regardless of being MText or Text. I solved the MText part but i don’t see the same nodes available for simple Text. Does anyone knows of an alternative? thank you.

this?2020-06-03_14-39-35

Hi Yien,
Is this a custom node? i don’t see them on my Dynamo or Civil3ToolKit.

nope it is out of the box.

On Dynamo for Civil3D? i opened all the menus and i cannot find them.

in Dynamo, just type in the search bar.
or right click in the main window to search for “Categories”

This is only available for Revit.

2 Likes

@csanchez I don’t think there is a node to change text contents. Maybe instead you can create new text in the same locations as the old and then erase the old?

The only Nodes under Categories that comes out when i typed “categories” are Clockwork Custom nodes and none of them gives me the Categories with a pull down option for Text Notes. I am running Dynamo for Civil3D. image

Thank you mzjensen, i was thinking about that but how about the content, orientation, location and insertion of the text. Can all that be retrieved from the text object?

@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:

1 Like

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()

@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:

That’s very easy one also:

i.TextString.upper()

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])

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?