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