CopySelection

Short description

Purpose: Duplicate only a chosen segment of a LWPolyline between two picked points and generate it on a selected layer Supported objects: Single LWPOLYLINE only Usage style: Extract partial polyline segments and place them on a different layer using a filterable layer picker dialog

Command:

Command name: CopySelection How to run: Type COPYSELECTION and press Enter Prompts sequence: Select LWPolyline → Specify 1st Point → Specify 2nd Point → Choose Layer Selection rules: Command stops if selected object is missing or not a LWPOLYLINE

Description:

The user selects an LWPolyline and then two points projected onto its geometry to define the segment to duplicate. A dialog appears allowing layer filtering, picking from a list, or selecting an object in the drawing to adopt its layer. The code calculates curve parameters between the two points, reconstructs only that portion with widths and bulges, and creates a new LWPolyline on the chosen layer.

Helper function: (if any)​

tan Computes tangent of an angle while avoiding division by near-zero cosine valuesLM:LWVertices Extracts LWPolyline vertex data such as point, widths, and bulgeget-all-layers Collects all non-xref layers, sorts them, and prepares them for the layer pickerupdate-layer-list Updates layer popup list in the dialog according to the typed filterDCL builder Creates a temporary dialog file containing filter input, layer list, pick-layer button, and OK/Cancel controls

Functionalities:

Polyline validation Ensures the selected object is a LWPOLYLINEPoint projection Snaps the picked points to the closest polyline points before using themDistinct point enforcement Rejects overlapping points and forces user to choose a valid second pointParameter order correction Swaps start and end parameters when reversed by selectionLayer dialog with memory Recalls last filter and layer using stored environment variablesLayer filtering Dynamically filters layer names using wildcard matchingPick layer from drawing Lets the user click any object to inherit its layerSegment extraction Reconstructs only the portion between the two parametric points including widths and bulgesNew polyline creation Builds a fresh LWPolyline with original properties but on the new layerCleanup Removes temporary DCL file after dialog closesCancellation handling Stops with a message if no valid layer is chosen

Result:

Segment duplication A new LWPolyline reproducing only the selected portion of the original is createdLayer assignment The new polyline is placed on the chosen layer without altering the original objectWorkflow benefit Enables quick extraction of partial runs for detailing, highlights, or separate layer controlSession persistence Stores last used filter and layer to speed up future usage

Images, animations etc.

Pixel

XAML code:

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:Autodesk.Windows;assembly=AdWindows">
    
<src:RibbonToolTip x:Key="CopySelection">
<src:RibbonToolTip.ExpandedContent>
<StackPanel>
<TextBlock Background="AntiqueWhite" TextAlignment="Left">
<Bold>Function Syntax: CopySelection</Bold>
<LineBreak/>
<Bold>Version: 1 Date: 01.11.2025</Bold>
<LineBreak/>
<LineBreak/>
<Hyperlink>AI + https://www.theswamp.org/index.php?topic=59415.0</Hyperlink>
<LineBreak/>
<Bold>Purpose</Bold><LineBreak/>
This program duplicates a selected segment of an LWPolyline between two user picked points, and creates the new polyline on a user selected layer chosen from a dialog with live name filtering or by picking a layer from an object in the drawing.<LineBreak/>
<LineBreak/>

<Bold>Primary Command</Bold><LineBreak/>
<Span Foreground="DarkRed"><Bold>CopySelection</Bold></Span> prompts for one LWPolyline, two points on it, then creates a new LWPolyline segment copy on a chosen layer.<LineBreak/>
<LineBreak/>

<Bold>User Workflow</Bold><LineBreak/>
1. Run <Span Foreground="DarkRed"><Bold>CopySelection</Bold></Span> in the AutoCAD command line.<LineBreak/>
2. Select one <Span Foreground="DarkRed"><Bold>LWPOLYLINE</Bold></Span> entity when prompted.<LineBreak/>
3. Specify the first point, then specify the second point, both of which are snapped to the closest points on the selected polyline.<LineBreak/>
4. A layer picker dialog opens, where the user can filter layers by name, select a layer from a dropdown list, or pick a layer from an existing object in the drawing.<LineBreak/>
5. If the user confirms a layer selection, the program duplicates only the polyline segment between the two points and creates a new polyline on the chosen layer.<LineBreak/>
<LineBreak/>

<Bold>Key Inputs and Validation</Bold><LineBreak/>
<ul><LineBreak/>
  <li><Bold>Polyline selection</Bold> The command requires selecting an entity and verifies it is of type <Span Foreground="DarkRed"><Bold>LWPOLYLINE</Bold></Span>.<LineBreak/></li><LineBreak/>
  <li><Bold>Two distinct points</Bold> The user must pick two different points, the routine re projects each pick to the closest point on the polyline using <Span Foreground="DarkRed"><Bold>vlax-curve-getclosestpointto</Bold></Span>, and it rejects identical points with a distinct points required message.<LineBreak/></li><LineBreak/>
  <li><Bold>Layer selection</Bold> The user must choose a valid layer in the dialog, otherwise the operation is cancelled without creating a new polyline.<LineBreak/></li><LineBreak/>
</ul><LineBreak/>
<LineBreak/>

<Bold>Layer Picker Dialog</Bold><LineBreak/>
The command dynamically writes a temporary DCL file and opens a dialog titled <Span Foreground="DarkRed"><Bold>Set Layer for New Polyline</Bold></Span>.<LineBreak/>
It supports filtering and a pick from drawing workflow.<LineBreak/>
<LineBreak/>

<Bold>Layer Filtering Behavior</Bold><LineBreak/>
<ul><LineBreak/>
  <li>The dialog has an edit box labeled <Span Foreground="DarkRed"><Bold>Filter by Name</Bold></Span> that filters the layer list to matching entries.<LineBreak/></li><LineBreak/>
  <li>The filter uses wildcard matching logic by surrounding the typed text with * so it behaves like contains match, and it uses case insensitive comparison by converting names to uppercase.<LineBreak/></li><LineBreak/>
  <li>The list of available layers excludes Xref dependent layers by skipping names that match the pattern containing a pipe character, which are typically Xref layer names.<LineBreak/></li><LineBreak/>
  <li>The dialog remembers the last used layer and last used filter using environment variables so subsequent runs start from the previous context.<LineBreak/></li><LineBreak/>
</ul><LineBreak/>
<LineBreak/>

<Bold>Pick Layer From Drawing</Bold><LineBreak/>
The dialog includes a button <Span Foreground="DarkRed"><Bold>Pick Layer From Drawing</Bold></Span> that closes the dialog temporarily, prompts the user to select an object, reads that object layer, and then re opens the dialog with that layer pre selected if it exists in the layer list.<LineBreak/>
<LineBreak/>

<Bold>Persistent Settings</Bold><LineBreak/>
The command stores and retrieves user preferences using environment variables.<LineBreak/>
<ul><LineBreak/>
  <li><Span Foreground="DarkRed"><Bold>PLDUPE_LastLayer</Bold></Span> stores the last chosen layer name, initially set to the original layer of the selected polyline as the default baseline.<LineBreak/></li><LineBreak/>
  <li><Span Foreground="DarkRed"><Bold>PLDUPE_LastFilter</Bold></Span> stores the last typed filter text for the layer dialog.<LineBreak/></li><LineBreak/>
</ul><LineBreak/>
<LineBreak/>

<Bold>Polyline Segment Duplication Logic</Bold><LineBreak/>
After layer confirmation, the routine duplicates only the portion of the polyline between the snapped points p and q, using curve parameters and vertex reconstruction logic derived from PLDUPE style behavior.<LineBreak/>
<LineBreak/>

<Bold>How the Segment Range is Determined</Bold><LineBreak/>
<ul><LineBreak/>
  <li>It computes curve parameters m and n at points p and q using <Span Foreground="DarkRed"><Bold>vlax-curve-getparamatpoint</Bold></Span>.<LineBreak/></li><LineBreak/>
  <li>If the parameters are reversed, it swaps m and n and also swaps p and q so the segment is processed in forward order along the polyline.<LineBreak/></li><LineBreak/>
  <li>It extracts LWPolyline vertex data using <Span Foreground="DarkRed"><Bold>LM:LWVertices</Bold></Span>, capturing each vertex point and width and bulge data for reconstruction.<LineBreak/></li><LineBreak/>
</ul><LineBreak/>
<LineBreak/>

<Bold>Bulge and Width Handling</Bold><LineBreak/>
<ul><LineBreak/>
  <li>The routine includes a tangent helper <Span Foreground="DarkRed"><Bold>tan</Bold></Span> and uses it to adjust bulge values when trimming at fractional parameters.<LineBreak/></li><LineBreak/>
  <li>If the start point p lies within a segment rather than exactly at a vertex, it inserts a new synthetic vertex at p with interpolated start width and adjusted bulge for the partial segment.<LineBreak/></li><LineBreak/>
  <li>If the end point q lies within a segment rather than exactly at a vertex, it inserts a new synthetic vertex at q and adjusts widths and bulge accordingly to end the duplicated segment cleanly.<LineBreak/></li><LineBreak/>
</ul><LineBreak/>
<LineBreak/>

<Bold>New Polyline Creation</Bold><LineBreak/>
The new polyline is created using <Span Foreground="DarkRed"><Bold>entmakex</Bold></Span>, reusing most of the original polyline entity data but substituting specific fields for the new entity.<LineBreak/>
<ul><LineBreak/>
  <li><Bold>Layer</Bold> The entity data is updated so group 8 is set to the user selected layer name.<LineBreak/></li><LineBreak/>
  <li><Bold>Closed flag</Bold> The closed bit is removed from group 70 so the new segment is not forced closed.<LineBreak/></li><LineBreak/>
  <li><Bold>Extrusion and normal</Bold> The routine preserves the polyline normal vector using group 210 from the original entity data to keep the new polyline oriented correctly in 3D context.<LineBreak/></li><LineBreak/>
  <li><Bold>Elevation and header data</Bold> It preserves elevation and header fields from the original LWPolyline by carrying forward group 39 and associated header data where applicable.<LineBreak/></li><LineBreak/>
</ul><LineBreak/>
<LineBreak/>

<Bold>Temporary File Cleanup</Bold><LineBreak/>
The command writes the dialog definition to a temporary DCL file and deletes it after the dialog workflow completes using <Span Foreground="DarkRed"><Bold>vl-file-delete</Bold></Span>.<LineBreak/>
<LineBreak/>

<Bold>Important Commands and Aspects</Bold><LineBreak/>
<Span Foreground="DarkRed"><Bold>CopySelection</Bold></Span> main command entry point.<LineBreak/>
<Span Foreground="DarkRed"><Bold>entsel</Bold></Span> used to select the LWPolyline and to pick an object for layer extraction.<LineBreak/>
<Span Foreground="DarkRed"><Bold>getpoint</Bold></Span> used to specify the two points, then projected to the polyline.<LineBreak/>
<Span Foreground="DarkRed"><Bold>vlax-curve-getclosestpointto</Bold></Span> snaps picked points onto the polyline accurately.<LineBreak/>
<Span Foreground="DarkRed"><Bold>PLDUPE_LastLayer</Bold></Span> remembers last selected layer across runs.<LineBreak/>
<Span Foreground="DarkRed"><Bold>PLDUPE_LastFilter</Bold></Span> remembers last filter text across runs.<LineBreak/>
<Span Foreground="DarkRed"><Bold>Pick Layer From Drawing</Bold></Span> lets the user derive a layer choice from an existing object.<LineBreak/>
<Span Foreground="DarkRed"><Bold>entmakex</Bold></Span> creates the new polyline representing the duplicated segment.<LineBreak/>
<LineBreak/>

<Bold>Messages and Edge Cases</Bold><LineBreak/>
<ul><LineBreak/>
  <li>If no entity is selected at the start, it prints a no entity selected message and exits with no changes.<LineBreak/></li><LineBreak/>
  <li>If the selected object is not an LWPolyline, it prints a not an LWPolyline message and exits with no changes.<LineBreak/></li><LineBreak/>
  <li>If the two picked points resolve to the same closest point on the polyline, it forces the user to pick a distinct second point.<LineBreak/></li><LineBreak/>
  <li>If the user cancels the dialog or does not confirm a layer, it prints a no layer selected operation cancelled message and does not create a new polyline.<LineBreak/></li><LineBreak/>
  <li>If the user picks a layer from an object that is not present in the layer list, it reports that the picked layer was not found and does not apply it as the selection.<LineBreak/></li><LineBreak/>
</ul><LineBreak/>
<LineBreak/>

<Bold>Operational Summary</Bold><LineBreak/>
This program will require the user to select an <Span Foreground="DarkRed"><Bold>LWPOLYLINE</Bold></Span>, then specify two distinct points which are projected onto that polyline, then choose a target layer using a dialog with name filtering or by picking a layer from an object, after which the program reconstructs and duplicates only the polyline segment between the two points including widths and bulges, creates a new polyline via <Span Foreground="DarkRed"><Bold>entmakex</Bold></Span> on the selected layer, preserves the original normal orientation, and cleans up the temporary dialog file while remembering the last used layer and filter for the next run.<LineBreak/>


</TextBlock>
            
<Grid>
<Image Source="PNG" Stretch="Uniform"/>
</Grid>

<Grid>
<MediaElement
Source="Rec 0010.gif"
Stretch="Uniform"
Visibility="Visible"/>
</Grid>

</StackPanel>
</src:RibbonToolTip.ExpandedContent>
</src:RibbonToolTip>
</ResourceDictionary>



Additional info:

Share this page:

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Tags: 🏷️ Autocad Lisps, 🏷️ Polyline menu
0
Would love your thoughts, please comment.x
()
x