I’d like to know if it’s possible to retrieve the geometry (specifically the rectangular boundary) that encloses the labels of pipes and structures in Civil 3D using Dynamo.
Hi @Diogo.Azevedo,
Try the Object.Extents
node and see if that gets you what you need.
Hi @zachri.jensen, using the Extents node I got the bounding box, but it’s not the same as the label’s border box.
OK, understood. There isn’t an easy way to get that border without exploding everything down.
I’m curious though, what are you ultimately trying to achieve in your workflow?
I’m trying to check if there is any interference between labels geometry.
Labels against labels, or labels against everything?
Labels against labels
Does Object.Geometry work?
You can copy them, explode, get the geometry and then delete the copies.
Did it to get the geometry once and it did work out really well (it was on the 2023 version, but I don’t see why it wouldn’t work now).
Not ideal, of course, but it works…
No
Can you post a sample drawing for review? It’s a long shot but I have an idea I can try in the morning if I have a dataset and a C3D version.
Unfortunately, there’s no way to copy a label. So I had to open the same DWG file in read-only mode (for safety), explode the labels, and that way I was able to get the geometry I needed.
The “extend” node captures everything from the location point of the pipe/structure to the rectangle that surrounds the text, which makes the resulting bounding box larger than it actually is.
@apegaia thanks for the sugestion.
Just checked here, you’re absolutely right. You can copy labels on the 2023 version of the Object.Copy node, but not on the 2025 one…
Since I didn’t want to open another drawing just to explode the labels, I ended up creating this small Python script to clone the labels and extract their geometry, which I’m using for label overlap detection.
# Load the Python Standard and DesignScript Libraries
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 *
# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN
lables_list = IN[0]
adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor
handles = []
with adoc.LockDocument():
db = adoc.Database
with db.TransactionManager.StartTransaction() as t:
# Espaço atual do modelo/layout
btr = t.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)
for label in lables_list: # Lista de labels
try:
original = t.GetObject(label.InternalObjectId, OpenMode.ForRead)
clone = original.Clone()
btr.AppendEntity(clone)
t.AddNewlyCreatedDBObject(clone, True)
# Obter handle da label clonada
handles.append(clone.Handle.ToString())
except:
handles.append(None) # Em caso de erro
t.Commit()
# Assign your output to the OUT variable.
OUT = handles
Awesome approach! Hadn’t thought about that!
Also, I believe there’s now a node to get the object handle directly (don’t remember if it used to exist before)