Author Topic: converting spline to polylines  (Read 15177 times)

0 Members and 1 Guest are viewing this topic.

DEVITG

  • Bull Frog
  • Posts: 465
converting spline to polylines
« on: July 12, 2004, 09:20:37 AM »
Hi all gurus , please I need to convert this all spline to Polylines.

the original file is acad 2000 , I have acad 2002

The lisp shall be to be used on acad 2000.


Thanks in advance.



http://theswamp.org/lilly.pond/devitg/spline-to%20poly.dwg
Location @ Córdoba Argentina Using ACAD 2019  at Window 10

CAB

  • Global Moderator
  • Seagull
  • Posts: 10395
converting spline to polylines
« Reply #1 on: July 12, 2004, 10:16:38 AM »
Here are two choices.
<untested>

Code: [Select]
(defun c:sptrace (/ ent spline cur pl end keep)
 (setq cur nil)
 (setq pl '((0 . "LWPOLYLINE")
     (100 . "AcDbEntity")
     (67 . 0)
     (8 . "0")
     (100 . "AcDbPolyline")
     (90 . 7)
     (70 . 0)
     (43 . 0.0)
     (38 . 0.0)
     (39 . 0.0)
    )
   )
 (setq end '(210 0.0 0.0 1.0));define polyline group codes
 (while (not (progn (princ "\rSelect Spline: ") ;select spline to convert
    (setq spline (ssget ":s" '((0 . "SPLINE"))))
     )
)
 )
 (initget "Yes No")
 (setq keep (getkword "Keep Original Spline [Yes/No]: "));keep original line or not
 (setq spline (ssname spline 0)); get ename
 (if (/= keep "No")
   (progn
     (entmake (entget spline));copy spline
     (setq spline (entlast));get ename of new spline
     )
   )
 (setq ent spline); copy ename to new variable
 (command "splinedit" ent "refine" "elevate" 26 "x" "x");add extra control points
 (setq ent (entget ent)); get data for spline
 (setq pl (subst (assoc 8 ent) (assoc 8 pl) pl)); set polylines layer to same as spline
 (if (= (rem (cdr (assoc 70 ent)) 2) 1);is spline closed
   (setq pl (subst (cons 70 1) (assoc 70 pl) pl));set polyline closed
   (setq pl (subst (cons 70 0) (assoc 70 pl) pl));set polyline open
 )
 (repeat (length ent);loop
   (progn
     (if (eq (car (car ent)) 10);get control point data
(setq cur (append cur (list (car ent))))
     )
     (setq ent (cdr ent));get next element in list
   )
 )
 (setq pl (subst (cons 90 (length cur)) (assoc 90 pl) pl));set number of points in polyline
 (repeat (length cur);loop
   (progn;add polyline point data
     (setq pl
    (append
      pl
      (list (car cur) (cons 40 0.0) (cons 41 0.0) (cons 42 0.0))
    )
     )
     (setq cur (cdr cur));get next element in list
   )
 )
 (setq pl (append pl (list end)));add normal vector to polyline data
 (entmake pl);make polyline
 (entdel (cdr (assoc -1 (entget spline))));entdel spline, original or copy
 (princ);exit quietly
)




Code: [Select]
;Convert SPLINES to PLINES - Mauricio Ferman©2001
(defun c:spl2pl (/ splines plinetype osmode i spl ed codepair)
  (if
    (setq splines (ssget (list (cons 0 "spline"))))
     (progn
       (if
         (zerop (setq plinetype (getvar "plinetype")))
          (setvar "plinetype" 1)
       ) ;if
       (setq osmode (getvar "osmode"))
       (setvar "osmode" 0)
       (setq i 0)
       (while
         (setq spl (ssname splines i))
          (setq i  (1+ i)
                ed (entget spl)
          ) ;setq
          (command ".pline")
          (foreach
                    codepair
                            ed
            (if
              (= 10 (car codepair))
               (command (cdr codepair))
            ) ;if
          ) ;foreach
          (command "")
          (command ".pedit" "l" "s" "")
       ) ;while
       (if plinetype
         (setvar "plinetype" plinetype)
       )
       (setvar "osmode" osmode)
     ) ;progn
  ) ;if
  (princ)
) ;defun
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Columbia

  • Guest
converting spline to polylines
« Reply #2 on: July 12, 2004, 10:18:57 AM »
Try this snippet.  What it does is step through the given spline at a given tolerance distance and pull a point off of the curve.  It then adds that point to a running list.  The snippet returns that list of points that you could then use to build your polyline.

Have fun!!

Code: [Select]

(vl-load-com)

(defun Spline->Pline (oSpline tol / 1stPoint dist fullLength lastPoint plinePoints point)
  (setq 1stPoint (vlax-curve-getPointAtParam oSpline (vlax-curve-getStartParam oSpline))
        lastPoint (vlax-curve-getPointAtParam oSpline (vlax-curve-getEndParam oSpline))
        fullLength (vlax-curve-getdistatparam oSpline (vlax-curve-getendparam oSpline))
        dist 0
        plinePoints (list 1stPoint)
  )
  (while (< (setq dist (+ dist tol)) fullLength)    
    (if (setq point (vlax-curve-getPointAtDist oSpline dist))
      (setq plinePoints (append plinePoints (list point)))
    )
  )
  (setq plinePoints (append plinePoints (list lastpoint)))
;;; Use the variable plinePoints (which is a list of vertex points)
;;; and whatever method you like to use for adding a polyline
;;; to the drawing.
)

DEVITG

  • Bull Frog
  • Posts: 465
spline to polyline
« Reply #3 on: July 12, 2004, 08:20:56 PM »
Hia CAB ,  thanks for your help

I did some changes , so the lisp would take all the splines and change one after one , erasing the splines, as follow.




Code: [Select]
;; TO CHANGE THE COLOR TO COLOR THE LAST OBJECT MADE

(DEFUN CHGC (COLOR)
  (COMMAND "._CHANGE" "L" "" "P" "C" COLOR "")
)
;;END CHANGE COLOR THE LAST



;;(defun c:sptrace (/ ent spline cur pl end keep) "to keep variable global while debug"
(defun c:sptrace ()
  (setq cur nil)
  (setq pl '((0 . "LWPOLYLINE")
    (100 . "AcDbEntity")
    (67 . 0)
    (8 . "0")
    (100 . "AcDbPolyline")
    (90 . 7)
    (70 . 0)
    (43 . 0.0)
    (38 . 0.0)
    (39 . 0.0)
   ) ;_end list
  ) ;_end setq pl
  (setq end '(210 0.0 0.0 1.0))  ;define polyline group codes
  (setq spline# (ssget "x" '((0 . "SPLINE")))) ;_ I change it just to check after a run
  (setq pl-leng (sslength spline#))
  (setq ss# 0)
  (repeat pl-leng
;;;(setq spline (ssname spline# ss#))
;;;(print spline)
;;;(setq ss# (1+ ss#))
;;;)



    ;;(while (not (progn (princ "\rSelect Spline: ") ;select spline to convert
    ;;(while
    ;;sget ":s" '((0 . "SPLINE"))))
    ;;(setq spline entnext)

    ;;   );_PROGN
    ;;);_NOT
    ;;);_WHILE
    ;;(initget "Yes No")
    ;;(setq keep (getkword "Keep Original Spline [Yes/No]: "));keep original line or not
;;;(setq keep "No")
    (setq spline (ssname spline# ss#))  ; get ename
;;; (if (/= keep "No")
;;;   (progn
;;;     (entmake (entget spline));copy spline
;;;     (setq spline (entlast));get ename of new spline
;;;     );_end progn
;;;   );_end if  
    (setq ent spline)  ; copy ename to new variable
    (command "splinedit" ent "refine" "elevate" 26 "x" "x")
 ;add extra control points
    (setq ent (entget ent))  ; get data for spline
    (setq pl (subst (assoc 8 ent) (assoc 8 pl) pl))
 ; set polylines layer to same as spline
    (if (= (rem (cdr (assoc 70 ent)) 2) 1)  ;is spline closed
      (setq pl (subst (cons 70 1) (assoc 70 pl) pl))
 ;set polyline closed
      (setq pl (subst (cons 70 0) (assoc 70 pl) pl))
 ;set polyline open
    )
    (repeat (length ent)  ;loop
      (progn
(if (eq (car (car ent)) 10)  ;get control point data
 (setq cur (append cur (list (car ent))))
)
(setq ent (cdr ent))  ;get next element in list
      )
    )
    (setq pl (subst (cons 90 (length cur)) (assoc 90 pl) pl))
 ;set number of points in polyline
    (repeat (length cur)  ;loop
      (progn  ;add polyline point data
(setq pl
      (append
pl
(list (car cur) (cons 40 0.0) (cons 41 0.0) (cons 42 0.0))
      )
)
(setq cur (cdr cur))  ;get next element in list
      )
    )
    (setq pl (append pl (list end)))  ;add normal vector to polyline data
    (entmake pl)  ;make polyline
    (CHGC 1);_to change  color
    (entdel (cdr (assoc -1 (entget spline))))  ;entdel spline, original or copy
    (princ)  ;exit quietly
    (setq ss# (1+ ss#))


  ) ;_repeat
) ;_end defun

(c:sptrace) ;_to run it from vlide
;|«Visual LISP© Format Options»
(72 2 50 2 nil "end of " 60 9 0 0 0 T T nil T)
;*** DO NOT add text below the comment! ***|;


But as you could see at this drawing , the polyline join both splines and change the profile.






http://theswamp.org/lilly.pond/devitg/after%20spline-to%20poly03.dwg




http://theswamp.org/lilly.pond/devitg/before%20spline-to%20poly03.dwg

http://theswamp.org/lilly.pond/devitg/before%20spline-to%20poly03.dwg
Location @ Córdoba Argentina Using ACAD 2019  at Window 10

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9719
converting spline to polylines
« Reply #4 on: July 12, 2004, 10:27:30 PM »
Columbia, Thats cool.

BTW, Long time... Where ya been?
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

Columbia

  • Guest
converting spline to polylines
« Reply #5 on: July 13, 2004, 07:44:22 AM »
I've been up to my eyeballs in work, so I haven't had a whole lot of time to peruse and kbitz here.  But things have lightened a little right now, therefore you see me!!  Although, I think it's just the calm before the storm.  But on a different note, I'm trying my best to learn VBA, and not be stuck as a one language guru.

But back to VLISP...  I took the snippet I added above and added to it so that it'll turn all SPLINES in a drawing to PLINES.

Code: [Select]

(vl-load-com)

(defun Spline->Pline (oSpline tol / 1stPoint dist fullLength lastPoint plinePoints point)
  (setq 1stPoint (vlax-curve-getPointAtParam oSpline (vlax-curve-getStartParam oSpline))
        lastPoint (vlax-curve-getPointAtParam oSpline (vlax-curve-getEndParam oSpline))
        fullLength (vlax-curve-getdistatparam oSpline (vlax-curve-getendparam oSpline))
        dist 0
        plinePoints (list 1stPoint)
  )
  (while (< (setq dist (+ dist tol)) fullLength)    
    (if (setq point (vlax-curve-getPointAtDist oSpline dist))
      (setq plinePoints (append plinePoints (list point)))
    )
  )
  (setq plinePoints (append plinePoints (list lastpoint)))
)

;; here comes the command line entry that will use
;; the above sub function.  This code has almost no error
;; checking.  Use error checking/handling as you see fit.
;; Also I have not debugged this code - hell, I haven't even
;; run it to see if it actually works!!  You'll just have to cut &
;; paste to see for yourself.

(defun c:spline2pline (/ ss i points point obj)
  (if (setq ss (ssget "X" (list (cons 0 "SPLINE"))))
    (progn
      (setq i 0)
      (repeat (sslength ss)
        (setq obj (vlax-ename->vla-object (ssname ss i))
             points (Spline->Pline obj)
        )
        (command "._pline")
        (foreach point points
          (command "_non" point)
        )
        (command "")
        (vla-delete obj)
      )
    )
  )
  (princ)
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10395
converting spline to polylines
« Reply #6 on: July 13, 2004, 08:59:25 AM »
You beat me to it.
I included the change layer, but if the layer is frozen or locked
the routine crashes.
Code: [Select]
(defun c:spl2pl(/ usrlay usrosm usrplw ent pdist idx ss )
  (setq usrosm (getvar "osmode"))
  (setq usrplw (getvar "plinewid"))
  (setvar "plinewid" 0 )
  (setvar "osmode" 0 )
  (setq pdist 36) ; distance between points on new pline
  (if (setq ss (ssget "X" '((0 . "SPLINE")))); get all splines
    (progn
      (setq idx (sslength ss))
      (while (>= (setq idx (1- idx)) 0)
        (setq ent (ssname ss idx))
        (if (setq plist (Spline->Pline ent pdist))
          (progn
            (command "._pline" )
            (mapcar '(lambda (x) (command x)) plist)
            (command "")
            (command "._change" "_Last" "" "_P" "_LA" (cdr(assoc 8(entget ent)))"")
            (entdel ent)
          ) ; progn
        ); endif
      ) ; while
    ) ; progn
    (prompt "\nNo splines in drawing.")
  ) ;endif
  (setvar "osmode" usrosm)
  (setvar "plinewid" usrplw)
  (princ)
);defun
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10395
converting spline to polylines
« Reply #7 on: July 13, 2004, 09:14:46 AM »
Ok, I think I overcame the layer pit fall & avoided the osmode catch
in my other version by using entmod.
Code: [Select]
(defun c:spl2pl(/ usrlay usrosm usrplw ent pdist idx ss pl plist pentlst)
  (setq pdist 36) ; distance between points on new pline
  (setq pentlst '((0 . "LWPOLYLINE")
     (100 . "AcDbEntity")
     (67 . 0)
     (8 . "0")
     (100 . "AcDbPolyline")
     (90 . 7)
     (70 . 0)
     (43 . 0.0)
     (38 . 0.0)
     (39 . 0.0)
    )
   )
  (setq end '(210 0.0 0.0 1.0));define polyline group codes
  (if (setq ss (ssget "X" '((0 . "SPLINE")))); get all splines
    (progn
      (setq idx (sslength ss))
      (while (>= (setq idx (1- idx)) 0)
        (setq ent (ssname ss idx)
              pl pentlst)
        (if (setq plist (Spline->Pline ent pdist))
          (progn
            (foreach x plist
              (setq pl (append pl
                        (list (cons 10 (list (car x)(cadr x)))
                              (cons 40 0.0)
                              (cons 41 0.0)
                              (cons 42 0.0))))
            )
            ;;set number of points in polyline
            (setq pl (append
                       (subst (cons 90 (length plist)) (assoc 90 pl) pl)
                       pl
                       (list end))
            )
            ;;  update layer
            (setq pl (subst (assoc 8 (entget ent)) (assoc 8 pl) pl))
            (entmake pl);make polyline
            (entdel ent)
          ) ; progn
        ); endif
      ) ; while
    ) ; progn
    (prompt "\nNo splines in drawing.")
  ) ;endif
  (princ)
);defun
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

daron

  • Guest
converting spline to polylines
« Reply #8 on: July 14, 2004, 09:19:49 AM »
These are great routines guys. I have a greater challenge, if anybody's really up for it. The production guys say that they need plines to be in the arcs of the spline. In other words, true arc plines. I've muddled through the dxf content and have even studied the (entget (car (entsel))) of a spline. I feel it can be done, but it seems to be a great challenge. So, if anybody wants to attempt this and get it working, I'd say you're a better lisp programmer than most, including that guy, Tony Tanzillo. I got a spline2pline that he wrote, and it is similar in end product to Columbia's, but longer in lisp content.

Columbia

  • Guest
converting spline to polylines
« Reply #9 on: July 14, 2004, 09:27:50 AM »
So you're saying you want arc segments to make up the pline instead of line segments?

SMadsen

  • Guest
converting spline to polylines
« Reply #10 on: July 14, 2004, 09:30:01 AM »
Oh, just to see that on the screen, "you are better than Tanzillo", would be worth it - no matter the real truth, of course  :)

If you take Columbia's approach and dig a little into vlax-curve-getFirstDeriv then I'm sure you'll be able to pull it off yourself, Daron.

SMadsen

  • Guest
converting spline to polylines
« Reply #11 on: July 14, 2004, 10:06:54 AM »
Apropos: Check out the last post here. It's the best explanation of curve derivatives I've seen.

daron

  • Guest
converting spline to polylines
« Reply #12 on: July 14, 2004, 12:43:14 PM »
Oh Stig, I want to and I was thinking those vlax-curves had to be the answer. I just haven't had a chance to do more than ponder the thought and try to figure out what makes a spline do what it does.

daron

  • Guest
converting spline to polylines
« Reply #13 on: July 14, 2004, 12:50:00 PM »
Stig, I can't as yet get in there. I've changed email and don't remember my password. Would there be any way you'd be able to copy and paste it to the swamp?

SMadsen

  • Guest
converting spline to polylines
« Reply #14 on: July 14, 2004, 05:56:22 PM »
With kind permission from Richard Sincovec:

"No, you can't use the second derivative on line segments. There's an explanation in linear algebra, and a possibly simpler one in topology once you reach the point where you can understand all the 3-ball and 2-sphere stuff, but the easiest explanation might be a sort of real-world analogy. AutoCAD works in 3-D, and most of us probably had our first real experience with derivatives in physics anyway, with stuff like v = xdt and so forth, so that approach might be the best.

Let's imagine a polyline as being the path a ball has travelled. As you remember from physics, a derivative is a rate of change. So, since we're assuming the polyline represents the position of the ball over time, the first derivative would be the velocity the ball is travelling at any particular instant in time. For straight segments, this velocity vector is in the same direction as the direction of travel. For curves, this is in a line tangent to the curve at that point. AutoCAD returns this direction vector, or first derivative, as simply a coordinate, the endpoint of a vector; the vector is assumed to start at (0,0,0). And, niftily enough, it looks like AutoCAD defined things so that the length of the vector is the length of the line for line segments, and the radius of the curve for arcs. (I wouldn't recommend using this function to get lengths or radii, though... It might have just turned out that way in the few items I checked in some poking around...)

Now, let's look at the second derivative. We remember from physics that this is acceleration, or how much the ball's velocity is changing. In other words, the second derivative is another directional vector, this one showing which way some invisible force would need to push the ball to make it travel along our polyline. And, again from our physics, this directional acceleration vector would be in the plane of the curve, and perpendicular to the direction of travel. In AutoCAD terms, the direction of this vector is perpendicular to the curve, toward its radius. And again, because of the way the math works, the length of the direction vector is equal to the radius of the curve.

However, with lines, the direction of travel is not changing. In physics terms, the lateral acceleration is 0. This implies the second derivative of a line segment must ALWAYS be 0, regardless of its direction. (Conversely, the second derivative of a curve must ALWAYS be non-zero.)"