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