Author Topic: Entmod LWpolyline vertex widths  (Read 3315 times)

0 Members and 1 Guest are viewing this topic.

Coltm16

  • Guest
Entmod LWpolyline vertex widths
« on: December 31, 2015, 05:29:03 PM »
Hello all. I am a newbie at AutoLisp, so please forgive inefficient and poorly formatted code with non-existent error trapping.

I am trying to write a code that will allow a user to select a polyline and apply a smooth uniform taper to a desired number of vertices. Similar to something like this from briscad:


The problem is when I apply the start and end width to any assoc 40 or 41, it applies it to all of them when I use entmod, sort of like a global taper for each segment. Am I doing something wrong, or is this not possible with autolisp?

Thanks in advance for any help. See commented code below.


Code: [Select]
(defun c:stp (/ ent elist n nn at vtx stwid endwid curwid factor)

(setq ent (car (entsel)))
(setq vtx (getint "\nNumber of vertexs: "));number of vertexes to apply smooth taper
(setq stwid (getreal "\nStart Width: "));start width of taper
(setq endwid (getreal "\nEnd Width: "));end width of taper
(setq curwid stwid);curwid will be the width applied to each end during while loop,
(setq factor (/ (- stwid endwid) vtx));subtract the factor from the width after each pass to ensure a smooth and even taper
(setq elist (entget ent))
(setq n 0);counter to iterate through all objects in list
(setq nn 0);seperate counter that counts start and end widths (40's and 41's)
(while (< nn vtx);while vertex counter is less than the number of vertexes supplied by user
(setq at (car (nth n elist)));get the nth item in list
(cond
((= at 40);if item is 40...
(setq elist (subst (cons 40 curwid) (nth n elist) elist));...set it to current width
(setq curwid (- curwid factor)));reduce current width by factor
((= at 41);if item is 41...
(setq elist (subst (cons 41 curwid) (nth n elist) elist));...set it to current width that has been reduced by factor
(setq nn (1+ nn)));increment vertex counter
);endcond
(setq n (1+ n));increment overall item counter
);end while
(setq elist (vl-remove (assoc 43 elist) elist));remove 43 (global width) or else segement widths will not update
(entmod elist);update ent
(entupd ent)
(princ) 
);end of function

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Entmod LWpolyline vertex widths
« Reply #1 on: December 31, 2015, 06:08:01 PM »
One problem I see is SUBST replaces all occurences in a list. Try the example below.
Code - Auto/Visual Lisp: [Select]
  1. (subst '(40.1) '(40.0) '((40.0) (40.0) (40.0) (40.0)))

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

ribarm

  • Gator
  • Posts: 3308
  • Marko Ribar, architect
Re: Entmod LWpolyline vertex widths
« Reply #2 on: December 31, 2015, 07:28:59 PM »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Entmod LWpolyline vertex widths
« Reply #3 on: January 01, 2016, 06:33:48 AM »
Welcome to the Swamp

Maybe :

Code - Auto/Visual Lisp: [Select]
  1.  
  2. (defun c:lwp (/ sdf s edf e ss en pl el bl ed fg cr dc td i
  3.                 sp ep bg sw ew vl)
  4.  
  5.   (setq sdf (if gv_tws gv_tws 1.0))
  6.   (initget 4)
  7.   (setq s (getdist (strcat "\nStarting Distance Width <" (rtos sdf 2 2) ">:   ")))
  8.   (or s (setq s sdf))
  9.   (setq gv_tws s)
  10.  
  11.   (setq edf (if gv_twe gv_twe 1.0))
  12.   (initget 4)
  13.   (setq e (getdist (strcat "\nEnding Distance Width <" (rtos edf 2 2) ">:   ")))
  14.   (or e (setq e edf))
  15.   (setq gv_twe e)
  16.  
  17.   (while (not en)
  18.          (and (princ "\nSelect 1 LWPOLYLINE To Edit")
  19.               (setq ss (ssget (list (cons 0 "LWPOLYLINE"))))
  20.               (= (sslength ss) 1)
  21.               (setq en (ssname ss 0))))
  22.  
  23.   (setq ed (entget en)
  24.         fg T)
  25.  
  26.   (foreach g ed
  27.  
  28.     (cond ((not fg))
  29.           ((= (car g) 43))
  30.           ((= (car g) 10)
  31.            (setq fg nil))
  32.           (T
  33.            (setq el (cons g el))))
  34.  
  35.     (cond ((= (car g) 10)
  36.            (setq pl (cons (cdr g) pl)))
  37.           ((= (car g) 42)
  38.            (setq bl (cons (cdr g) bl)))))
  39.  
  40.   (setq pl (reverse pl))
  41.   (setq bl (reverse bl))
  42.   (setq el (reverse el))
  43.  
  44.   (setq td 0
  45.          i 0)
  46.  
  47.   (repeat (1- (length pl))
  48.       (setq sp (nth i pl)
  49.             ep (nth (1+ i) pl)
  50.             bg (nth i bl)
  51.             td (+ td (if (zerop bg)
  52.                          (distance sp ep)
  53.                          (abs (* (/ (distance sp ep)
  54.                                  (* 2.0 (sin (* 2.0 (atan bg)))))
  55.                               (* (atan bg) 4.0)))))
  56.              i (1+ i)))
  57.  
  58.   (setq cr (/ (abs (- s e)) td))
  59.   (if (> s e)
  60.       (setq cr (- cr)))
  61.  
  62.   (setq dc 0
  63.         i 0)
  64.   (repeat (1- (length pl))
  65.       (setq sw (+ s (* cr dc)))
  66.       (setq sp (nth i pl)
  67.             ep (nth (1+ i) pl)
  68.             bg (nth i bl)
  69.             dc (+ dc (if (zerop bg)
  70.                          (distance sp ep)
  71.                          (abs (* (/ (distance sp ep)
  72.                                  (* 2.0 (sin (* 2.0 (atan bg)))))
  73.                               (* (atan bg) 4.0))))))
  74.       (setq ew (+ s (* cr dc)))
  75.       (setq vl (append vl (list (cons 10 (nth i pl))
  76.                                 (cons 40 sw)
  77.                                 (cons 41 ew)
  78.                                 (cons 42 (nth i bl)))))
  79.       (setq i (1+ i)))
  80.  
  81.   (setq vl (append vl (list (cons 10 (last pl))
  82.                             (cons 40 ew)
  83.                             (cons 41 ew)
  84.                             (cons 42 (last bl)))))
  85.  
  86.   (setq el (append el vl))
  87.   (setq el (append el (list (assoc 210 ed))))
  88.   (entmod el)
  89.  
  90.   (prin1))
  91.  
  92.  


This would work only with the entire length of the lwpolyline, not a selected quantity of vertices.

-David
« Last Edit: January 02, 2016, 08:25:08 AM by David Bethel »
R12 Dos - A2K

Coltm16

  • Guest
Re: Entmod LWpolyline vertex widths
« Reply #4 on: January 01, 2016, 09:03:46 AM »
Thank you David. Works beautiful. I could always break the polyline where I want it to taper to, run the routine, then join the polyline back again.

Here was the ugly solution I came up with yesterday after posting using Pedit, but I've read that using (command...) is slower than using (entmod). Thanks again.

Code - Auto/Visual Lisp: [Select]
  1. (defun c:stg (/ ent elist n nn at vtx stwid endwid curwid factor)
  2.  
  3. (setq ent (car (entsel)))
  4. (setq vtx (getint "\nNumber of vertexs: "));number of vertexes to apply smooth taper
  5. (setq stwid (getreal "\nStart Width: "));start width of taper
  6. (setq endwid (getreal "\nEnd Width: "));end width of taper
  7. (setq curwid stwid);curwid will be the width applied to each end during while loop,
  8. (setq factor (/ (- stwid endwid) vtx));subtract the factor from the width after each pass to ensure a smooth and even taper
  9. (setq n 0);counter to iterate through all objects in list
  10. (setq nn 0);seperate counter that counts start and end widths (40's and 41's)
  11.   (command "pedit" ent "E" "W" curwid (setq curwid (- curwid factor)) "N")
  12.   (repeat (- vtx 1)
  13.         (command "w" curwid (setq curwid (- curwid factor)) "N")       
  14.     )
  15.   (command "x" "")
  16.  
  17. (princ)  
  18. );end of function

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Entmod LWpolyline vertex widths
« Reply #5 on: January 01, 2016, 09:37:01 AM »
Glad you got it working.

To ensure a truly constant taper, you will need to compare the distance from the start point to the current point to the overall length of the pline.

If the vertex is at 47.5% of the entire length, then the width at that vertex should be the starting width plus 47.5% of the delta

I did not take the length of arc segment vs the chord length into consideration, but the start and ends are exact.  There is probably a vl- call that would return a more exact value for each point.

-David

PS (entmod) vs (command...)  They both have their good points and bad points.  Don'e be afraid of either.  With today's hardware, speed is not that much of a factor as is their respective complexity vs idiosyncrasies. 
« Last Edit: January 01, 2016, 09:45:18 AM by David Bethel »
R12 Dos - A2K

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Entmod LWpolyline vertex widths
« Reply #6 on: January 01, 2016, 07:04:22 PM »
This thread inspired me to create this new program: Polyline Taper:


ronjonp

  • Needs a day job
  • Posts: 7531
Re: Entmod LWpolyline vertex widths
« Reply #7 on: January 01, 2016, 07:28:54 PM »
Very cool Lee  :)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Entmod LWpolyline vertex widths
« Reply #8 on: January 01, 2016, 07:35:33 PM »

Coltm16

  • Guest
Re: Entmod LWpolyline vertex widths
« Reply #9 on: January 01, 2016, 08:43:04 PM »
Awesome Lee. Thank you so much. Can't wait to try it out.

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Entmod LWpolyline vertex widths
« Reply #10 on: January 02, 2016, 05:46:10 AM »
Awesome Lee. Thank you so much. Can't wait to try it out.

You're most welcome Coltm16 - it was a fun program to write  :-)

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Entmod LWpolyline vertex widths
« Reply #11 on: January 02, 2016, 07:38:07 AM »
Nice Lee,

You made me go back and add the true arc length to distances. LOL

I do think it take someone with a very good eyesight to catch the error.  :-o

Have great holiday !  -David
R12 Dos - A2K

Lee Mac

  • Seagull
  • Posts: 12926
  • London, England
Re: Entmod LWpolyline vertex widths
« Reply #12 on: January 02, 2016, 07:48:34 AM »
Nice Lee,

You made me go back and add the true arc length to distances. LOL

I do think it take someone with a very good eyesight to catch the error.  :-o

Have great holiday !  -David

Thanks David  :-)

I agree - I just couldn't leave it alone knowing the width is ever so slightly off...  :evil:

Happy New Year!

David Bethel

  • Swamp Rat
  • Posts: 656
Re: Entmod LWpolyline vertex widths
« Reply #13 on: January 02, 2016, 01:04:35 PM »
LOL

A little OCD attack kicking in ?   :laugh:


http://www.theswamp.org/index.php?topic=50708.0
R12 Dos - A2K