Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Draw MLINE via LISP

5 REPLIES 5
Reply
Message 1 of 6
dreadnoult
2543 Views, 5 Replies

Draw MLINE via LISP

Hello everyone.

 

I have drawings with a lot of polyline objects. I need a routine which will draw multilines by coordinates of vertexes of this polylines. For example, if there is a pline with coordinates 10,10 - 20,20 i want to draw in other layer MLINE with the same coordinates. I know it's should be simple but can not gues how to do it. I've never used LISP before. Could anybody help me?

 

Thank you.

5 REPLIES 5
Message 2 of 6
Lee_Mac
in reply to: dreadnoult

Try this quick draft:

 

(defun c:pl2ml ( / e i l s )
    (if (setq s (ssget '((0 . "LWPOLYLINE"))))
        (repeat (setq i (sslength s))
            (setq e (ssname s (setq i (1- i)))
                  l (entget e)
            )
            (apply 'command
                (append '("_.mline")
                    (apply 'append
                        (mapcar
                            (function
                                (lambda ( x )
                                    (list "_non" (trans (cdr x) e 1))
                                )
                            )
                            (vl-remove-if-not '(lambda ( x ) (= 10 (car x))) l)
                        )
                    )
                    (if (= 1 (logand 1 (cdr (assoc 70 l)))) '("_C") '(""))
                )
            )
        )
    )
    (princ)
)
Message 3 of 6
dreadnoult
in reply to: Lee_Mac

Yes it is! Thank you very much! It is exactly what i tried to do. 

Message 4 of 6
dreadnoult
in reply to: Lee_Mac

Lee_Mac, could you explain please in a couple of words how your routine works? I know, it's magic, but it would be usefull for me to know 🙂
Message 5 of 6
Lee_Mac
in reply to: dreadnoult

You're welcome dreadnoult Smiley Happy

 

Here is a brief overview of the program to help with your understanding:

 

(defun c:pl2ml ( / e i l s )
    ;; Define function, declare local variables.
    ;; To understand why variable localisation is important, see http://bit.ly/15Qw104
    
    (if ;; If the following expression returns a non-nil value
 
        (setq s
            ;; Assign the following value to the symbol 's'
            ;; e.g. s = <Selection set: 2d6> (a pointer)

            (ssget '((0 . "LWPOLYLINE")))
            ;; Retrieve a selection set from the user
            ;; permitting selection of LWPOLYLINE entities
            ;; For a full reference of the SSGET function, see http://bit.ly/137NmOJ
            
        ) ;; end SETQ

        ;; Start 'then' argument of IF function:
        
        (repeat ;; repeat the following expressions a fixed number of times
            
            (setq i (sslength s))
            ;; Assign the number of items in the selection set to the symbol 'i'
            ;; and pass this number as an argument to the REPEAT function indicating
            ;; the number of times to repeat the loop.
            ;;
            ;; If three objects are selected, i = 3
            
            (setq e (ssname s (setq i (1- i)))
            ;; Decrement the local variable 'i' by one and assign the entity
            ;; residing at this position in the selection set to the symbol 'e'
            ;; e.g. e = <Entity a1b2c3> (a pointer)
                
                  l (entget e)
            ;; Retrieve the list of DXF data for entity 'e' and assign this list
            ;; to the symbol 'l'
            ;; e.g. l = ((0 . "LWPOLYLINE") (5 . "ABC") ... )
                
            ) ;; end SETQ
            
            (apply 'command
                ;; Apply the COMMAND function to the following list of arguments
                
                (append '("_.mline")
                    ;; Append the string "_.mline" to the list of arguments
                    
                    (apply 'append
                        ;; Apply the APPEND function to the following list of arguments
                        
                        (mapcar
                            ;; Evaluate the following (anonymous) function on every
                            ;; item in the supplied list.
                            ;; See http://bit.ly/14SEDo3 for an explanation of mapcar/lambda

                            ;; Define an anonymous function to be evaluated by MAPCAR on every
                            ;; item in the given list
                            (function
                                ;; The anonymous lambda function takes a single argument 'x'
                                ;; representing each item in the list
                                (lambda ( x )
                                    ;; Construct a list of the string "_non" and
                                    ;; the LWPolyline vertex transformed to the active UCS
                                    (list "_non" (trans (cdr x) e 1))
                                    ;; TRANS is required as all commands require points expressed
                                    ;; relative to the active UCS and LWPolyline vertices are
                                    ;; expressed relative to the OCS of the LWPolyline entity.
                                    ;; For more information on the OCS, see http://bit.ly/14kLFhx
                                    
                                ) ;; end LAMBDA
                                
                            ) ;; end FUNCTION

                            ;; Iterate over the DXF data list and remove any dotted pairs
                            ;; whose first element is not equal to 10
                            ;; (i.e. remove all but DXF group 10 pairs - the polyline vertices)
                            (vl-remove-if-not

                                ;; Define another anonymous LAMBDA function to pass to the
                                ;; VL-REMOVE-IF-NOT function.
                                ;; For an explanation of the apostrophe, see http://bit.ly/1bW3rQK
                                '(lambda ( x ) (= 10 (car x)))

                                l ;; The DXF data for entity 'e'
                                 
                            ) ;; end VL-REMOVE-IF-NOT
                            
                        ) ;; end MAPCAR
                        
                    ) ;; end APPLY

                    ;; If the value of DXF group 70 contains bit-code 1
                    ;; indicating that the LWPOLYLINE is closed...
                    (if (= 1 (logand 1 (cdr (assoc 70 l))))

                       '("_C") ;; Then return the list: ("_C") - i.e. Close the MLine

                       '("")   ;; Else return the list: ("") - i.e. End the MLine command
                        
                    ) ;; end IF
                    
                ) ;; end APPEND

                ;; The constructed list of arguments supplied to the APPLY function will
                ;; look something like this:
                ;;
                ;; ("_.mline" "_non" (1.23 3.45 5.67) "_non" (3.13 4.14 5.15) ... "_C")
                
            ) ;; end APPLY
            
        ) ;; end REPEAT

        ;; We have not supplied an 'else' argument to the IF function in this case.
        
    ) ;; end IF
    
    (princ) ;; Suppress the return of the last evaluated expression
    
) ;; end DEFUN - function is defined.

 

I must apologise as the program is written in a more functional style, which may be more difficult for a beginner to understand than an equivalent imperative style.

Message 6 of 6
Kent1Cooper
in reply to: dreadnoult


@dreadnoult wrote:

.... 

I have drawings with a lot of polyline objects. I need a routine which will draw multilines by coordinates of vertexes of this polylines. ....


Here's another way to do it:

 

(defun C:MLOP (/ plss); = MultiLine(s) Over Polyline(s)
  (if (setq plss (ssget '((0 . "LWPOLYLINE"))))
    (repeat (setq i (sslength plss))
      (command "_.mline")
      (foreach pt
        (mapcar 'cdr ; get point locations from all vertices
          (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget (ssname plss (setq i (1- i)))))
        ); mapcar
        (command "_none" pt); feed out to Mline
      ); foreach
      (command (if (vlax-curve-isClosed (ssname plss i)) "_c" "")); end Mline
    ); repeat
  ); if
  (princ)
); defun

 

Consider also whether you want to remove the Polylines, and/or surround the whole thing in an Undo begin/end wrapper, and/or add error handling, etc.  Also, do any of the Polylines ever contain arc segments?  You won't be able to duplicate those in an Mline, but you could approximate them in segmented form.

Kent Cooper, AIA

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost