An AutoLisp utility for preserving LWPOLYLINE geometry while inserting new vertices.
At a Glance
| Motivation | Utility to insert vertices on Polyline segments. |
| Software | AutoCAD and its Verticals |
| Supports: Line & Arc segments, Self-intersecting Polylines, and uniform width segments. | |
Finding the ‘Raison d'être’ For the Application:
Why this Application was Needed
To find answers to my questions, I decided to do a quick internet search. Results weren't discouraging.
The search revealed that AutoCAD users across multiple domains frequently perform the task of adding vertices to plines.
People insert additional nodes (vertices) into an AutoCAD polyline segment for several practical reasons:
- Match surveyed coordinates, design constraints, or construction details.
- Provide more grip points, making it easier to stretch, move, or align specific portions of the polyline.
- Civil engineering, GIS, CNC machining, and other applications sometimes require vertices at specific locations for calculations, staking, machine paths, or data exchange.
- Roads, property boundaries, utility lines, contours, and similar features often need multiple vertices to capture changes in direction or geometry.
- Additional vertices create exact points that can be used as object snaps (OSNAP) when drawing or positioning other objects.
Click to display details of survey
Domain |
Tasks |
Typical Vertices per Polyline |
Typical Segment Length |
|---|---|---|---|
| Civil Engineering & Surveying |
|
20–500+ | 5–50 m |
| 4–100 | 1–200 m | ||
| GIS |
|
20–1000+ | 5–50 m |
| Architecture |
|
4–50 | 0.5–20 m |
| Mechanical Drafting | Custom profiles, sheet-metal outlines, and tool paths. | 10–200 | 1–100 mm |
| Electrical and Utility Design |
|
10–300 | 2–50 m |
An observation that caught my eye: For AutoCAD usage patterns, civil engineering, surveying, and GIS users typically insert vertices into polylines more frequently than other domains because they need to model irregular real-world geometry accurately.
Preparing the ground – Revisiting the basics:
Background and Fundamentals
- Native AutoCAD commands like pline / pedit
- Data generated by a Custom program
- Imported data (like .dxf)
- The properties Elevation, Endpoint and Global width are defined at assembly level. These are delegated to the segments. (Width is an exception. It can be overridden at segment level.)
Begin with end in mind – The Scope:
Application Scope
- Insert vertices at fixed distance. The length of the last new segment may be different and at the end of the current segment.
- Insert vertices at equal distances along a segment.
It will:
- Work with arc segments. (I was very particular about this because most of the pline processing codes skip arcs
and self- intersecting plines for obvious reasons)
Many utilities that insert vertices into polylines simplify the problem by avoiding difficult cases. This application was designed to address those cases rather than bypass them.
These situations occur regularly in production drawings, but many utilities either ignore them or handle them only partially because they significantly increase implementation complexity
Supports arc segments, allowing curved polylines to be processed without converting them into straight-line approximations.
Preserves uniform-width representation, avoiding unexpected changes to polyline width behavior. - Retain the original status of drawing (except new vertices) and create no new anomaly in the drawing.
- Ensures polyline dependent activities continue to works with modified pline exactly as they were working with original pline. - hatch / region / Offset / area / break / explode
- Maintain integrity (status / values
of properties as displayed in the 'Properties Pallet') of original pline with no side effects
after inserting vertices:
These properties are length, area, 'Closed' state, elevation, start and end vertex, arcs stability (radius and center), only uniform widths, pline direction (cw / ccw), node sequence, layer, original width representation.
Click to display Explainer: Maintaining Status
I will explain why maintaining status is important with a very interesting example. We will do an interactive exercise so you don't need any proof. The important point to note is that the presence or absence of value in the Global width box indicates the current width behavior of the pline - Global or Per Segment.. This causes a little inconvenience while writing code. Many times Programmers may overlook this. The code may end up changing the width behavior. The 'AddVertices' application takes care of this and maintains the behavior exactly as it was - retaining the original value in the Global width box. |
More importantly, here is what the Application will not do:
- Replace the original pline with a new one, but will strictly modify it.
- Create temporary geometry which needs to be deleted subsequently.
- Do any quality checks or repair 'faults' in the pline. (It will strictly follow the principle 'Garbage In, Garbage Out').
Walking the Talk – How Application Works:
These are the basic steps (algorithm) the Application internally follows:
- Collect from the pline.
- Generate data for each segment by processing the pline data (including segment length).
- Generate new vertices by dividing segment lengths by distance.
- Calculate modified bulges (representation of included angle of arc) if it's an arc.
- Collect all node related data sequentially and apply that to original pline to modify it.
Also, it does not require that pline must be visible on the screen.
Trial By Fire - The Choke Test:
Testing and Validation
I designed a 'Choke' test (crash test) for testing the Application.
The express purpose of the test was to verify that the Application behaves consistently irrespective of the amount of data to process - It does not 'choke' up and cause frustration and feeling of uncertainty to the User. The input parameters used for the test were - Insertion interval 10 with 0.1 as tolerance and equal length segments (which I believe is that bit tougher than fixed distance method.)
I also created a test case drawing specifically for this test. (It is included as .dxf file in the download.)
Click to display contents of test drawing
Domain |
Tasks |
Typical Vertices per Polyline |
Typical Segment Length |
|---|---|---|---|
| Civil Engineering & Surveying |
|
20–500+ | 5–50 m |
| 4–100 | 1–200 m | ||
| GIS |
|
20–1000+ | 5–50 m |
| Architecture |
|
4–50 | 0.5–20 m |
| Mechanical Drafting | Custom profiles, sheet-metal outlines, and tool paths. | 10–200 | 1–100 mm |
| Electrical and Utility Design |
|
10–300 | 2–50 m |
The 'Choke Test' repeatedly processes the drawing in each cycle and modifies the original plines.
Click to display summary of modifications
| Before Modification | After Modification | Additions | ||
|---|---|---|---|---|
| Length | 2386.0249 | 2386.0249 | 0.0 | |
| Segments | Line segments | 28 | 62 | 34 |
| Arc segments | 20 | 197 | 177 | |
| Total | 48 | 259 | 211 | |
| Nodes | 45 | 255 | 210 |
The table 'Modification Summary' below, displays consolidates geometric parameters before and after modification by Application in each cycle of the 'Choke Test'.
And here are the results of Choke test
No. of cycles |
Time (in MilliSeconds) |
|
|---|---|---|
| No. of Cycles | Total | Per Cycle |
| 1 | < 0.0000 | < 0.0000 |
| 100 | 516.0000 | 5.1600 |
| 1000 | 5162.0000 | 5.1620 |
| 5000 | 25165.0000 | 5.0330 |
| 10000 | 50590.0000 | 5.0590 |
| 30000 | 148947.0000 | 4.9649 |
The absolute values may differ due to various factors like hardware configurations and working environment (multiple applications running simultaneously. The focus here is on consistency of time taken per cycle.
Also, to just give you in idea, when the test drawing is processed for 30000 cycles, it deals with (255 * 30000 = 7, 650, 000 nodes - yes more than 7 million nodes) in 148947 milliseconds (150 seconds / 2.5 minutes)
Evaluation:
During the evolution process of the Application, I submitted the Application for evaluation 4 times to ChatGPT. Here are some of the selected comments posted by ChatGPT:
I would classify the code as production-quality AutoLISP, not merely a working utility.This is **strong production-quality AutoLISP code** with good geometric reasoning. It goes well beyond typical hobby scripts and shows real CAD automation experience.
For a utility intended for **native AutoCAD LWPOLYLINEs**, the code you've shown demonstrates a strong understanding of both AutoLISP and polyline geometry. The arc-center/radius verification is probably the strongest piece of evidence you've presented that the geometric side is implemented correctly.
Those (Choke Test) results significantly strengthen the case that the implementation is mature from a geometric and algorithmic perspective.
The evidence you've provided suggests the implementation is doing exactly what it claims to do, and doing it efficiently. The fact that the per-cycle timing stays flat out to 10,000 iterations is probably the strongest rebuttal to concerns about the list-building strategy.
This affair with ChatGPT was an unusual cocktail of satisfaction, revelations, elation, disappointments, anger, frustration & disgust. But that's another story. (As way say in Hindi, 'Woh kissa fir kabhee'.)
Using the Application:
You can download and extract the contents of the attached .zip file. The 'AddVerices.vlx file is the application file. Note: The other files included are the sample test drawing 'AddVertecisChokeTest.dxf' & a sample calling function 'CallAdvertices.lsp'.
This Application is primarily designed as core function that will be called from a wrapper calling function to process multiple plines in the drawing. A typical way to call this Application is to use (SanKul_addVertices <entity name of pline> distance tolerance ifFixedDistance) at command prompt or from the calling function.
The arguments:
- entity name of the pline to process.
- The interval (spacing) at which to insert vertices
- Spacing Tolerance
- True / Nil flag to indicating the use of fixed / equal interval
The Application will return any one of the values in the AutoLISP list format '(pline handle . “Status message.)'
Here is an example of typical feedback: (plineHandle . "Skipped: insertSpacing not numeric OR not +ve")
A User without coding knowledge can use it for processing a single pline using following steps:
- Using 'appload' command load the vlx file.
- At command prompt, type (SanKul_addVertices (car (entsel)) distance tolerance ifFixedDistance)
- If you miss selecting the pline, Application will immediately respond to you with (plineHandle . "Skipped: not a pline."). You can repeat the step until you get the result.
- When successful, the feedback message will appear at the command prompt - (plineHandle . "Done: x node(s) inserted")
If you want to process multiple plines using complex selection (all plines in the drawing, plines only on specific layer etc.), you will need to write a calling wrapper function that typically creates a selection set. It then calls the vlx file in a loop to process each pline in the selection set.
I have attached a sample calling function (using AutoLISP) that explains this in more detail.
Roadmap For the Future:
Now that the basic infrastructure is well established, it is possible add few variations if strongly needed:
Use .dxf file as direct input. This will work without any installation of AutoCAD.
Batch processing multiple drawings
Adding vertices only to specific segment(s) of a pline.
Inserting vertices at specific locations on or near a pline.
In fixed distance, locate the unequal segment at the start / end or middle of the segment.
But this can complicate things - what exactly is middle when no of segments are even. (In case of 4 segments, which position is middle position - second or third?
Inserting vertices at irregular interval.
Insert vertices at fixed (not calculated) equal length ignoring segment boundaries.
Insert vertices so that each segment is converted into equal no. of segments.
Generate a virtual selection Window / Crossing for selection from a pline that contains arcs.
Break or Divide plines at uniform / randomly specified intervals / vertices.
Final Thoughts:
Feedback
As the cliche' goes, 'The real test - I mean taste - of pudding is in eating'.
So, I request you to test this Application and give honest feedback - especially where this Application does not work as expected (bugs). Your suggestions for improvement or addition of features are most welcome.
Suggestions, bug reports and enhancement requests are welcome. Real-world testing feedback helps improve the application and future releases.

