FeatureLine to Polyline 2D

Hi,
I created a script which does the following:

  1. Copy selected feature line
  2. Move copied feature line all points Z to 0
  3. 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 ?
    FLto2D v2.dyn (41.1 KB)

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.

Any ideas why script makes Feature Line uneditiable ?

Have you tried a different approach?FL to 2D poly

4 Likes

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

FeatureLineBaseCurve

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

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

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.

Also, here’s discussion on the other side of the house: Solved: Feature Line to Polyline 2D - Autodesk Community

Nice code sample @zachri.jensen :grinning: , 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]]
2 Likes

Nice additions @Alex.ColeAAFHE, thanks.

Hey folks,

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.