Explode copied and modified feature line to polyline 2D
but after exploding feature line to polyline I am not able to edit original feature line anymore.
Any thought about this ?
It looks like your whole script is only doing stuff to the copy. You’d need to create a second branch directly off the select objects node if you wanted to edit the original.
Are you wanting to get a 2D polyline and leave the original Feature Line untouched, or are you wanting to delete the original Feature Line when finished?
I want to leave original FL untouched.
I dont need edit the original FL within a script. Ive just said that my script do the job but after running a script it is not possible to edit FL manually in C3D.
@kovacsv this is close but isn’t quite correct for Feature Line arc segments because the FeatureLine.PolyCurve node tessellates the curves to create an approximation. The “pure” way to do it would be to recreate the segments from the bulge values.
import clr
clr.AddReference('AcMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AeccDbMgd')
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *
from Autodesk.Civil.DatabaseServices import *
from Autodesk.Civil import *
def extract_basecurve(featureLines):
output=[]
obj=[]
if not featureLines:
return
if not isinstance(featureLines,list):
featureLines = [featureLines]
adoc = Application.DocumentManager.MdiActiveDocument
with adoc.LockDocument():
with adoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
for featureLine in featureLines:
obj = featureLine.InternalDBObject
if isinstance(obj, FeatureLine):
# Get bulge values
bulges=[]
for i in range(0,obj.PointsCount-1):
bulges.Add(obj.GetBulge(i))
bulges.append(0)
# Get all points
pntsAll=obj.GetPoints(FeatureLinePointType.AllPoints)
lstPntsAll=[]
for i in pntsAll:
lstPntsAll.append(Point2d(i.X,i.Y))
# Get PI points
pntsPI=obj.GetPoints(FeatureLinePointType.PIPoint)
lstPntsPI=[]
for j in pntsPI:
lstPntsPI.append(Point2d(j.X,j.Y))
# Get indices of PI points
index=[]
for pt in lstPntsPI:
index.append(lstPntsAll.index(pt))
# Create filtered list of bulge values
filterBulge=[]
for k in index:
filterBulge.append(bulges[k])
# Polyline constructor
pl = Polyline()
bt = t.GetObject(db.BlockTableId, OpenMode.ForRead)
btr = t.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite)
# Add vertices
for l in range(0,len(lstPntsPI)):
pl.AddVertexAt(l,lstPntsPI[l],filterBulge[l],0,0)
# Add entity to database
btr.AppendEntity(pl)
t.AddNewlyCreatedDBObject(pl, True)
output.append(pl)
t.Commit()
return output
OUT = extract_basecurve(IN[0])
I don’t think feature lines like the object.copy node. Likely better to find a different method of processing the feature line in Dynamo and returning a polyline to Civil 3D.
My guess is that one thing that is going on has to do with Civil object names and it seems if you use Object.Copy on a civil object it will replicate the same name and as soon as that is created and Civil doesn’t like that, even if you rename it afterwards.
Nice code sample @zachri.jensen , if obj.Closed is True we don’t need to reduce obj.PointsCount by 1. Something like this works if obj is closed or not. See lines 35 to 39. Also if obj.Closed is True I’d also recommend closing the Polyline instance being create, see lines 73 to 75.
import clr
clr.AddReference('AcMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AeccDbMgd')
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *
from Autodesk.Civil.DatabaseServices import *
from Autodesk.Civil import *
def extract_basecurve(featureLines):
output=[]
obj=[]
if not featureLines:
return
if not isinstance(featureLines,list):
featureLines = [featureLines]
adoc = Application.DocumentManager.MdiActiveDocument
with adoc.LockDocument():
with adoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
for featureLine in featureLines:
obj = featureLine.InternalDBObject
if isinstance(obj, FeatureLine):
# Get bulge values
bulges=[]
if obj.Closed is True:
count = obj.PointsCount
else:
count = obj.PointsCount - 1
for i in range(count):
bulges.Add(obj.GetBulge(i))
bulges.append(0)
# Get all points
pntsAll=obj.GetPoints(FeatureLinePointType.AllPoints)
lstPntsAll=[]
for i in pntsAll:
lstPntsAll.append(Point2d(i.X,i.Y))
# Get PI points
pntsPI=obj.GetPoints(FeatureLinePointType.PIPoint)
lstPntsPI=[]
for j in pntsPI:
lstPntsPI.append(Point2d(j.X,j.Y))
# Get indices of PI points
index=[]
for pt in lstPntsPI:
index.append(lstPntsAll.index(pt))
# Create filtered list of bulge values
filterBulge=[]
for k in index:
filterBulge.append(bulges[k])
# Polyline constructor
pl = Polyline()
bt = t.GetObject(db.BlockTableId, OpenMode.ForRead)
btr = t.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite)
# Add vertices
for l in range(0,len(lstPntsPI)):
pl.AddVertexAt(l,lstPntsPI[l],filterBulge[l],0,0)
# Close the polyline where applicable
if obj.Closed is True:
pl.Closed = True
# Add entity to database
btr.AppendEntity(pl)
t.AddNewlyCreatedDBObject(pl, True)
output.append(pl)
t.Commit()
return output
OUT = [extract_basecurve(x) for x in IN[0]]
Just wanted to note here that Civil 3D 2025.1 has lots of new nodes for feature lines. In particular, the FeatureLine.Curve2D node should make this easy. The image below shows how to get the Dynamo geometry, and then creating polylines can be accomplished with the Object.ByGeometry node.