Python Script to Extract Polyline X, Y Values

Yes. You are correct! My bad. I forgot closing the polyline changes the indexes. Fixed with a simple if statement:

ExtractPoints.dyn (8.0 KB)

# 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 *

from Autodesk.DesignScript.Geometry import Point

# Import references from Civil3D
from Autodesk.Civil.ApplicationServices import *

# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN

adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor

with adoc.LockDocument():

    with adoc.Database as db:

        with db.TransactionManager.StartTransaction() as t:
            
            errorReport = None
            
            try:
                
                polyLineList = []
                selectedPolylines = IN[0]
                
                for polyline in selectedPolylines:
                    
                    polyLinePoints = []
                    realObject = polyline.AcObject
 
                    if isinstance(realObject, Polyline):
                        
                        if realObject.Closed:
                            indexNum = int(realObject.EndParam)
                        else:
                            indexNum = int(realObject.EndParam)+1
                            
                        for i in range(indexNum):                            
                            point = realObject.GetPoint2dAt(i)                            
                            polyLinePoints += [[point.X,point.Y]]
                            
                        polyLineList += [polyLinePoints]
            
            except:
            
                import traceback
                errorReport = traceback.format_exc()
                
            # Commit before end transaction
            t.Commit()

# Assign your output to the OUT variable.
if errorReport == None:
    OUT = polyLineList
else:
    OUT = errorReport

That works - thank you! Do you think it is possible to get the output of your script to run into the a script I already put together to remove excess x and y vertices for these shapes? I am not sure how to get these nested x and y values into the script I already put together. Node with the python script I created is attached.
Remove excess x and y vertices.dyn (3.9 KB)

A solution using ProtoGeometry (purge points by comparing 2 successive vectors)

remove extras points

import sys
import clr

clr.AddReference('ProtoGeometry')
import Autodesk.DesignScript.Geometry as DS

clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')

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 *

from Autodesk.DesignScript.Geometry import Point
from Autodesk.Civil.ApplicationServices import *

clr.AddReference('Python.Included')
import Python.Included as pyInc
path_py3_lib = pyInc.Installer.EmbeddedPythonHome
sys.path.append(path_py3_lib + r'\Lib\site-packages')

import numpy as np

dataEnteringNode = IN

adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor

with adoc.LockDocument():

    with adoc.Database as db:

        with db.TransactionManager.StartTransaction() as t:
            
            errorReport = None
            
            try:
                
                polyLineList = []
                selectedPolylines = IN[0]
                
                for polyline in selectedPolylines:
                    
                    polyLinePoints = []
                    pline = polyline.AcObject
 
                    if isinstance(pline, Polyline):
                        
                        pline = t.GetObject(pline.ObjectId, OpenMode.ForWrite)
                        purgeDSPts = []
                        arr_del_idx = np.array([])
                        # convert all points to Proto
                        DSPoints = [DS.Point.ByCoordinates(pline.GetPoint3dAt(i).X, 
                                                            pline.GetPoint3dAt(i).Y,
                                                            pline.GetPoint3dAt(i).Z) \
                                                            for i in range(pline.NumberOfVertices)]
                        # purge points by comparing 2 successive vectors
                        purgeDSPts = [DSPoints.pop(0), DSPoints.pop(0)]
                        start_idx = len(purgeDSPts) - 1
                        for idx, pt in enumerate(DSPoints):
                            vectA = DS.Vector.ByTwoPoints(purgeDSPts[-2], purgeDSPts[-1])
                            vectB = DS.Vector.ByTwoPoints(purgeDSPts[-1], pt)
                            if vectA.IsParallel(vectB):
                                # replace the last point
                                purgeDSPts[-1] = pt
                                # add index to delete
                                arr_del_idx = np.append(arr_del_idx, [start_idx + idx ])
                            else:
                                purgeDSPts.append(pt)
                        # remove extras points
                        while len(arr_del_idx) > 0:
                            # get the first and remove it from the np array
                            del_idx, arr_del_idx = arr_del_idx[0], arr_del_idx[1:]
                            print(del_idx)
                            pline.RemoveVertexAt(del_idx)
                            # decrement all index in np array
                            arr_del_idx -= 1
            except:
            
                import traceback
                errorReport = traceback.format_exc()
                
            t.Commit()

if errorReport == None:
    OUT = purgeDSPts
else:
    OUT = errorReport
3 Likes

This looks awesome! Thank you!

I am running into an error when I try it myself, though. Screenshot below. Any thoughts?

1 Like

Since application is not called on line 5, I think it safe to say you missed your imports when copying the code above.

1 Like

you are right - i don’t know how I did get all of the code copied over. Thank you!!!

2 Likes

Honestly I do the same thing 2x a day, so I only was able to pick up on it because of my own familiarity with the issue… and I’m usually moving from notepad where ctrl+a ctrl+c prevents it rather than the forum…

1 Like