Author Topic: - = { Challenge } = - convert curve fit old 2d heavy pline to spline  (Read 2064 times)

0 Members and 1 Guest are viewing this topic.

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Like it's written in the title... Only the challenge is consisted in the fact that I don't want to use CVREBUILD command... I want it to be done in any other way and I want the result to be as possible as equal to reference polyline... Let's see if someone can do it...

BTW. I know this isn't possible, but who knows...

M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2139
  • class keyThumper<T>:ILazy<T>
Re: - = { Challenge } = - convert curve fit old 2d heavy pline to spline
« Reply #1 on: July 26, 2016, 08:48:39 AM »
< .. >... Let's see if someone can do it...

BTW. I know this isn't possible, but who knows...

M.R.

Are you offering a prize as inducement and incentive ??
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: - = { Challenge } = - convert curve fit old 2d heavy pline to spline
« Reply #2 on: July 26, 2016, 09:04:17 AM »
< .. >... Let's see if someone can do it...

BTW. I know this isn't possible, but who knows...

M.R.

Are you offering a prize as inducement and incentive ??

I was just trying to awake inspiration in someone that follows the topic... Of course I don't have prize, it's just informative, to see if someone is willing to share something I or maybe other have missed...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: - = { Challenge } = - convert curve fit old 2d heavy pline to spline
« Reply #3 on: July 26, 2016, 12:25:12 PM »
Here is what I've got, but it's applicable only if simple cases (no self intersecting, or newly programmed LINE do not cross pline) :

Code - Auto/Visual Lisp: [Select]
  1. (defun c:oldheavyfit2spl ( / *error* *adoc* ss pl sp ep li e )
  2.  
  3.  
  4.   (defun *error* ( m )
  5.     (vla-endundomark *adoc*)
  6.     (if m
  7.       (prompt m)
  8.     )
  9.     (princ)
  10.   )
  11.  
  12.   (prompt "\nPick old heavy 2d polyline that is curve fited...")
  13.   (setq ss (ssget "_+.:E:S:L" (list '(0 . "POLYLINE") '(-4 . "<or") '(70 . 2) '(70 . 3) '(70 . 130) '(70 . 131) '(-4 . "or>"))))
  14.   (if ss
  15.     (if (or (= (cdr (assoc 70 (entget (setq pl (ssname ss 0))))) 2) (= (cdr (assoc 70 (entget (setq pl (ssname ss 0))))) 130))
  16.       (progn
  17.         (setq sp (vlax-curve-getstartpoint pl))
  18.         (setq ep (vlax-curve-getendpoint pl))
  19.         (setq li (entmakex (list '(0 . "LINE") (cons 10 sp) (cons 11 ep))))
  20.         (command "_.REGION" (ssadd li ss) "")
  21.         (command "_.CONVTOSURFACE" (entlast) "")
  22.         (command "_.CONVTONURBS" (entlast) "")
  23.         (setq e (entlast))
  24.         (command "_.OFFSETEDGE" "_non" sp "_D" "0.0")
  25.         (while (< 0 (getvar 'cmdactive))
  26.           (command "")
  27.         )
  28.         (entdel e)
  29.         (command "_.BREAK" (entlast) "_non" sp "_non" ep)
  30.         (command "_.JOIN" "_non" sp "_non" ep "")
  31.       )
  32.       (progn
  33.         (setq sp (vlax-curve-getstartpoint pl))
  34.         (command "_.REGION" ss "")
  35.         (command "_.CONVTOSURFACE" (entlast) "")
  36.         (command "_.CONVTONURBS" (entlast) "")
  37.         (setq e (entlast))
  38.         (command "_.OFFSETEDGE" "_non" sp "_D" "0.0")
  39.         (while (< 0 (getvar 'cmdactive))
  40.           (command "")
  41.         )
  42.         (entdel e)
  43.       )
  44.     )
  45.   )
  46.   (*error* nil)
  47. )
  48.  

I am looking forward to see if someone can do it better for every case...
Regards, M.R.
« Last Edit: July 26, 2016, 04:00:00 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Stefan

  • Bull Frog
  • Posts: 319
  • The most I miss IRL is the Undo button
Re: - = { Challenge } = - convert curve fit old 2d heavy pline to spline
« Reply #4 on: July 26, 2016, 07:29:58 PM »
Marko, as a guy who doesn't want to use a built-in command, you are using a lot of (command....

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / m2p a b e f1 f2 i k m p p1 p2 v w)
  2.   (defun m2p (a b) (mapcar '(lambda (a b) (/ (+ a b) 2.0)) a b))
  3.   (if
  4.     (setq e (car (entsel)))
  5.     (progn
  6.       (setq i (fix (vlax-curve-getendparam e))
  7.             k (list i)
  8.             )
  9.       (repeat i
  10.         (setq p1 (vlax-curve-getpointatparam e i)
  11.               f1 (vlax-curve-getfirstderiv e i)
  12.               m  (vlax-curve-getpointatparam e (- i 0.5))
  13.               k  (append (list i i) k)
  14.               p2 (vlax-curve-getpointatparam e (setq i (1- i)))
  15.               f2 (vlax-curve-getfirstderiv e i)
  16.               v  (inters p1 (mapcar '+ p1 f1)
  17.                          p2 (mapcar '+ p2 f2)
  18.                          nil
  19.                          )
  20.               p  (append (list v p1) p)
  21.               w  (append (list (/ (distance (m2p p1 p2) m) (distance m v)) 1.0) w)
  22.               )
  23.         )
  24.       (setq k (append '(0.0 0.0 0.0) k)
  25.             p (cons p2 p)
  26.             w (cons 1.0 w)
  27.             )
  28.       (entmake
  29.         (append
  30.           (list
  31.             '(0 . "SPLINE")
  32.             '(100 . "AcDbEntity")
  33.             '(100 . "AcDbSpline")
  34.             '(70 . 12)
  35.             '(71 . 2)
  36.             (cons 72 (length k))
  37.             (cons 73 (length p))
  38.             '(74 . 0)
  39.             '(42 . 1.0e-010)
  40.             '(43 . 1.0e-010)
  41.           )
  42.           (mapcar '(lambda (k) (cons 40 k)) k)
  43.           (apply 'append
  44.             (mapcar
  45.               '(lambda (p w)
  46.                  (list (cons 10 p) (cons 41 w))
  47.                )
  48.               p w
  49.             )
  50.           )
  51.         )
  52.       )
  53.     )
  54.   )
  55.   (princ)
  56. )

ronjonp

  • Needs a day job
  • Posts: 7529
Re: - = { Challenge } = - convert curve fit old 2d heavy pline to spline
« Reply #5 on: July 26, 2016, 08:56:29 PM »
Stefan,

The code above errors for me at (distance m v) because 'v' returns nil.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: - = { Challenge } = - convert curve fit old 2d heavy pline to spline
« Reply #6 on: July 26, 2016, 11:14:44 PM »
Stefan, I like your version, but it has lacks... See attached DWG... Here is my second attempt and yes, it's again using (command ...) calls, but it works to me till now and I had no problems...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:2ndss2spls ( / *error* arc2spl line2spl loop sss i ent ssss )
  2.  
  3.  
  4.   (defun *error* ( msg )
  5.     (if msg (prompt msg))
  6.     (princ)
  7.   )
  8.  
  9.   (defun arc2spl ( e / make_spline points q1 q2 a pc f pe ps w )
  10.  
  11.            (setq q1 (vlax-curve-GetStartParam e)
  12.                  q2 (vlax-curve-GetEndParam e)
  13.                  a  (/ (- (vlax-curve-GetEndParam e) (vlax-curve-GetStartParam e)) 3.0) ; a - parameter interval... and angle
  14.                  pc (mapcar                              ; pc - points on contur
  15.                       (function
  16.                         (lambda (p)
  17.                          (vlax-curve-GetPointAtParam e p)
  18.                           )
  19.                         )
  20.                       (list q1 (+ q1 a) (- q2 a) q2)
  21.                     )
  22.                  f  (mapcar                               ; f - first deriv on pc
  23.                       (function
  24.                         (lambda (p)
  25.                           (vlax-curve-GetFirstDeriv e p)
  26.                           )
  27.                         )
  28.                       (list q1 (+ q1 a) (- q2 a) q2)
  29.                     )
  30.                  pe (mapcar                              ; pe - extra control points for spline construction
  31.                       (function
  32.                         (lambda (p1 p2 d1 d2)
  33.                           (inters p1 (mapcar '+ p1 d1)
  34.                                   p2 (mapcar '+ p2 d2)
  35.                                   nil
  36.                                   )
  37.                         )
  38.                       )
  39.                      pc (cdr pc) f (cdr f)
  40.                     )
  41.                  ps  (list (car pc) (car pe) (cadr pc) (cadr pe) (caddr pc) (caddr pe) (cadddr pc)) ; ps - control points for spline
  42.                  w   (list 1.0 (cos (/ a 2)) 1.0 (cos (/ a 2)) 1.0 (cos (/ a 2)) 1.0)  ; weights for spline
  43.            )
  44.  
  45.     (defun make_spline ( pts )
  46.       (entmakex
  47.         (append
  48.            '((0 . "SPLINE") (100 . "AcDbEntity") (100 . "AcDbSpline")
  49.               (70 . 4) (71 . 2) (72 . 10) (73 . 7) (74 . 0)
  50.               (42 . 1.0e-010) (43 . 1.0e-010)
  51.               (40 . 0.0) (40 . 0.0) (40 . 0.0) (40 . 1.0) (40 . 1.0)
  52.               (40 . 2.0) (40 . 2.0) (40 . 3.0) (40 . 3.0) (40 . 3.0))
  53.            pts
  54.         )
  55.       )
  56.     )
  57.  
  58.     (defun points ( p w )
  59.       (apply 'append (mapcar '(lambda (a b) (list (cons 10 a) (cons 41 b))) p w))
  60.     )
  61.  
  62.     (entdel e)
  63.     (make_spline (points ps w))
  64.    
  65.   )
  66.  
  67.   (defun line2spl ( e / sp ep d )
  68.  
  69.     (setq sp (cdr (assoc 10 (entget e)))
  70.           ep (cdr (assoc 11 (entget e)))
  71.           d (distance sp ep)
  72.     )
  73.  
  74.     (entdel e)
  75.  
  76.     (entmakex
  77.       (list
  78.         '(0 . "SPLINE") '(100 . "AcDbEntity") '(100 . "AcDbSpline") '(210 0.0 0.0 1.0) '(71 . 1) '(73 . 2)
  79.         '(42 . 1.0e-010) '(43 . 1.0e-010) '(40 . 0.0) '(40 . 0.0) (cons 40 d) (cons 40 d) (cons 10 sp) (cons 10 ep)
  80.       )
  81.     )
  82.    
  83.   )
  84.  
  85.   (setq loop T)
  86.   (setq sss (ssget "_I"))
  87.   (if
  88.     (and
  89.       sss
  90.       (vl-some '(lambda ( x ) (wcmatch (cdr (assoc 0 (entget x))) "LINE,ARC,*POLYLINE")) (vl-remove-if 'listp (mapcar 'cadr (ssnamex sss))))
  91.     )
  92.     (setq loop nil)
  93.   )
  94.   (while loop
  95.     (setq sss (ssget "_:L" (list '(-4 . "<or") '(0 . "LINE,ARC,LWPOLYLINE") '(-4 . "<and") '(0 . "POLYLINE") '(-4 . "<or") '(70 . 0) '(70 . 1) '(70 . 8) '(70 . 9) '(70 . 128) '(70 . 129) '(-4 . "or>") '(-4 . "and>") '(-4 . "or>"))))
  96.     (if sss (setq loop nil))
  97.   )
  98.   (setq ssss (ssadd))
  99.   (repeat (setq i (sslength sss))
  100.     (setq ent (ssname sss (setq i (1- i))))
  101.     (cond
  102.       ( (eq (cdr (assoc 0 (entget ent))) "LINE")
  103.         (line2spl ent)
  104.         (ssadd (entlast) ssss)
  105.       )
  106.       ( (eq (cdr (assoc 0 (entget ent))) "ARC")
  107.         (arc2spl ent)
  108.         (ssadd (entlast) ssss)
  109.       )
  110.       ( (eq (cdr (assoc 0 (entget ent))) "LWPOLYLINE")
  111.         (sssetfirst nil (ssadd ent))
  112.         (c:lw2spl)
  113.         (ssadd (entlast) ssss)
  114.         (sssetfirst nil nil)
  115.       )
  116.       ( (and
  117.           (eq (cdr (assoc 0 (entget ent))) "POLYLINE")
  118.           (or
  119.             (eq (cdr (assoc 70 (entget ent))) 0)
  120.             (eq (cdr (assoc 70 (entget ent))) 1)
  121.             (eq (cdr (assoc 70 (entget ent))) 128)
  122.             (eq (cdr (assoc 70 (entget ent))) 129)
  123.           )
  124.         )
  125.         (command "_.CONVERTPOLY" "_L" ent)
  126.         (while (> (getvar 'cmdactive) 0) (command ""))
  127.         (sssetfirst nil (ssadd ent))
  128.         (c:lw2spl)
  129.         (ssadd (entlast) ssss)
  130.         (sssetfirst nil nil)
  131.       )
  132.       ( (and
  133.           (eq (cdr (assoc 0 (entget ent))) "POLYLINE")
  134.           (or
  135.             (eq (cdr (assoc 70 (entget ent))) 8)
  136.             (eq (cdr (assoc 70 (entget ent))) 9)
  137.           )
  138.         )
  139.         (sssetfirst nil (ssadd ent))
  140.         (c:3p2spl)
  141.         (ssadd (entlast) ssss)
  142.         (sssetfirst nil nil)
  143.       )
  144.     )
  145.   )
  146.   (sssetfirst nil ssss)
  147.   (*error* nil)
  148. )
  149.  
  150. (defun c:oldheavyfit2spl ( / *error* *adoc* ss pl sp e sss )
  151.  
  152.  
  153.   (defun *error* ( m )
  154.     (vla-endundomark *adoc*)
  155.     (if m
  156.       (prompt m)
  157.     )
  158.     (princ)
  159.   )
  160.  
  161.   (prompt "\nPick old heavy 2d polyline that is curve fited...")
  162.   (setq ss (ssget "_+.:E:S:L" (list '(0 . "POLYLINE") '(-4 . "<or") '(70 . 2) '(70 . 3) '(70 . 130) '(70 . 131) '(-4 . "or>"))))
  163.   (if ss
  164.     (progn
  165.       (setq pl (ssname ss 0))
  166.       (setq sp (vlax-curve-getstartpoint pl))
  167.       (command "_.EXPLODE" pl)
  168.       (while (< 0 (getvar 'cmdactive))
  169.         (command "")
  170.       )
  171.       (sssetfirst nil (ssget "_P"))
  172.       (c:2ndss2spls)
  173.       (setq sss (cadr (ssgetfirst)))
  174.       (setq e (car (nentselp (trans sp 0 1))))
  175.       (command "_.JOIN" e sss "")
  176.     )
  177.   )
  178.   (*error* nil)
  179. )
  180.  

M.R.
« Last Edit: July 27, 2016, 06:15:40 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Stefan

  • Bull Frog
  • Posts: 319
  • The most I miss IRL is the Undo button
Re: - = { Challenge } = - convert curve fit old 2d heavy pline to spline
« Reply #7 on: July 27, 2016, 04:47:07 AM »
Stefan,

The code above errors for me at (distance m v) because 'v' returns nil.
Curve fit polylines are nothing more than a bunch of arcs.
It might happen to get an arc of 180deg or it might be replaced by a line, but i guess only after editing or stretching the polyline.
These are the only cases when v is nil and both can be solved.
For the first case you need to divide the arc in 2 segments. You need to do so for arcs larger than 180deg also.
For the second, v=m and w=1.0.



ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: - = { Challenge } = - convert curve fit old 2d heavy pline to spline
« Reply #8 on: July 27, 2016, 08:10:00 AM »
Curve fit polylines are nothing more than a bunch of arcs.
...

Thanks Stefan for the explanation... I finally ended by exploding curve fit polyline and then convert arcs back to LWPOLYLINE which is also very thankful curve type and maybe even better than spline for my bigger lisp... Unfortunately I can't post that code as it has copyright info, but I am pleased it ended this way, even better than I thought... Now all 2d curve types are included in my lisp and that was my intention in the first place... So thank you for the info, although you see that your version has some lacks, I don't use it anyway...

Very thankful, Marko R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube