# FeatureLine to Polyline 2D

**URL:** <https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366>\
**Category:** Civil 3D\
**Created:** [August 20, 2021, 11:34am UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366 "2021-08-20T11:34:01Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![jakubstan](https://avatars.discourse-cdn.com/v4/letter/j/e19adc/32.png) [@jakubstan](https://forum.dynamobim.com/u/jakubstan)\
**Post date:** [August 20, 2021, 11:34am UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366/1 "2021-08-20T11:34:01Z")

</div>

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_2021-08-20_01-33-02](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/0/b/0be7dc9cc23480a5745d60edcd586c78be2afd77.png)  
[FLto2D v2.dyn](https://forum.dynamobim.com/uploads/short-url/f20FIfCMGO5HsVBxcHVRlYIPbZY.dyn) (41.1 KB)

---

<div class="post-metadata">

**Author:** ![KirkWM](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/kirkwm/32/104406_2.png) [@KirkWM](https://forum.dynamobim.com/u/KirkWM)\
**Post date:** [August 20, 2021, 3:08pm UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366/2 "2021-08-20T15:08:56Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![mzjensen](https://avatars.discourse-cdn.com/v4/letter/m/b77776/32.png) [@mzjensen](https://forum.dynamobim.com/u/mzjensen)\
**Post date:** [August 20, 2021, 3:24pm UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366/3 "2021-08-20T15:24:23Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![jakubstan](https://avatars.discourse-cdn.com/v4/letter/j/e19adc/32.png) [@jakubstan](https://forum.dynamobim.com/u/jakubstan)\
**Post date:** [August 20, 2021, 7:35pm UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366/5 "2021-08-20T19:35:37Z")

</div>

I want to leave original FL untouched.  
I don`t need edit the original FL within a script. I`ve just said that my script do the job but after running a script it is not possible to edit FL manually in C3D.

---

<div class="post-metadata">

**Author:** ![jakubstan](https://avatars.discourse-cdn.com/v4/letter/j/e19adc/32.png) [@jakubstan](https://forum.dynamobim.com/u/jakubstan)\
**Post date:** [August 23, 2021, 2:52pm UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366/6 "2021-08-23T14:52:20Z")

</div>

Any ideas why script makes Feature Line uneditiable ?

---

<div class="post-metadata">

**Author:** ![kovacsv](https://avatars.discourse-cdn.com/v4/letter/k/f6c823/32.png) [@kovacsv](https://forum.dynamobim.com/u/kovacsv)\
**Post date:** [August 23, 2021, 4:00pm UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366/7 "2021-08-23T16:00:48Z")

</div>

Have you tried a different approach? ![FL to 2D poly](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/4/7/47fc519d9fcac558516c086646dc2c77576b8ddf.gif)

 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/6/a/6a1fd8622285867e4326223ab895800e7cf319a9.png)

---

<div class="post-metadata">

**Author:** ![mzjensen](https://avatars.discourse-cdn.com/v4/letter/m/b77776/32.png) [@mzjensen](https://forum.dynamobim.com/u/mzjensen)\
**Post date:** [August 23, 2021, 5:45pm UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366/8 "2021-08-23T17:45:55Z")

</div>

> [@kovacsv](#):
>
> Have you tried another approach?

@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](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/3/f/3f09f0c35ca16e58b94804b624f25ac92ad4c304.gif)

```auto
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])

```

---

<div class="post-metadata">

**Author:** ![KirkWM](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/kirkwm/32/104406_2.png) [@KirkWM](https://forum.dynamobim.com/u/KirkWM)\
**Post date:** [August 23, 2021, 6:46pm UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366/9 "2021-08-23T18:46:37Z")

</div>

> [@jakubstan](#):
>
> Any ideas why script makes Feature Line uneditiable ?

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](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/b/f/bf78850460800ebb4a3bdf7740dfda68a3ab3c1f.png)

---

<div class="post-metadata">

**Author:** ![KirkWM](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/kirkwm/32/104406_2.png) [@KirkWM](https://forum.dynamobim.com/u/KirkWM)\
**Post date:** [August 23, 2021, 7:27pm UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366/10 "2021-08-23T19:27:59Z")

</div>

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](https://forums.autodesk.com/t5/civil-3d-forum/feature-line-to-polyline-2d/td-p/10560249)

---

<div class="post-metadata">

**Author:** ![Alex.ColeAAFHE](https://avatars.discourse-cdn.com/v4/letter/a/ecb155/32.png) [@Alex.ColeAAFHE](https://forum.dynamobim.com/u/Alex.ColeAAFHE)\
**Post date:** [August 24, 2021, 5:17pm UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366/11 "2021-08-24T17:17:36Z")

</div>

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.

```auto
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]]

```

---

<div class="post-metadata">

**Author:** ![mzjensen](https://avatars.discourse-cdn.com/v4/letter/m/b77776/32.png) [@mzjensen](https://forum.dynamobim.com/u/mzjensen)\
**Post date:** [August 24, 2021, 6:18pm UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366/12 "2021-08-24T18:18:28Z")

</div>

Nice additions @Alex.ColeAAFHE, thanks.

---

<div class="post-metadata">

**Author:** ![zachri.jensen](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/zachri.jensen/32/205331_2.png) [@zachri.jensen](https://forum.dynamobim.com/u/zachri.jensen)\
**Post date:** [August 23, 2024, 6:42pm UTC](https://forum.dynamobim.com/t/featureline-to-polyline-2d/67366/13 "2024-08-23T18:42:45Z")

</div>

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.

 ![image](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/d/1/d1130345ee47786f36f195512d6b1a37f4520987.png)
