Jump to content

Recommended Posts

Posted

Ok, so I have already done a lisp that goes through a polyline (Heavy polyline). It draws a circle in each point so that it shows that it identifies every point. Now, I have to modify this polyline, but just changing the coordinates of some points, the polyline will still have the same amounts of points. Ok, so, I have to be able to create a routine in lisp that identifies which points of the polyline have been changed, and, that it draws or inserts as texts the coordinates of this modified point. Drawing the text is easy, I'm having difficulties identifying which points of the polyline have changed.

 

I'm thinking maybe a way is modifying the routine and saving it as another routine. One routine would be to save the original polyline in a variable with setq, then the second routine, the modified one, will make a comparison between the two variables (onlye the coordinates of each point clearly) and then drawing in text the differences, however this seems not very user friendly and not really well thought as an efficient method.

 

So 2 questions, Does anyone have any better ideas? Is there a way to make this just one routine in lisp?

Posted

Hello

 

If you supported codes, that would be easier for all to try to help, and if you don't want to show your complete routine. So you can bring the part where the problem lays in.

 

Thanks & regards

 

Tharwat

Posted

Perhaps use an ObjectReactor to save a point/index list (triggered before modification) and compare using another callback (triggered after modification).

Posted
Perhaps use an ObjectReactor to save a point/index list (triggered before modification) and compare using another callback (triggered after modification).

 

Here's the code to go through the polyline.

 

(defun c:rpoli()
     (setq spoli (car (entsel "\nSelec. poligono. ")))
     (setq bpoli (entget spoli))
     (setq poli1 spoli) 
     (setq c (cdr (assoc 10 bpoli)))
     (while (/= "SEQEND" (cdr (assoc '0 bpoli)))
            (setq vert (cdr (assoc 10 bpoli)))
        (command "circle" vert "0.5")
            (setq spoli  (entnext spoli) bpoli (entget spoli))
      );wh
)

 

I'm new to Lisp, not so new to AutoCad however, but still new. So I don't know a lot of things yet, like ObjectReactor, don't know what is that.

 

I'm having an idea, however I'm having problems with saving useful data in the lisp. For example, I was thinking in an auxiliary variable that saved me spoli in poli1 like I put up there, then the program to compare would be (incomplete).

 

(defun c:dpoli()
     (setq spoli (car (entsel "\nSelec. poligono. ")))
     (setq bpoli (entget spoli))
     (setq poli2 poli1)
     (setq bpoli2 (entget poli2))
     (setq c (cdr (assoc 10 bpoli)))
     (while (/= "SEQEND" (cdr (assoc '0 bpoli)))
            (setq vert (cdr (assoc 10 bpoli)))
            (setq vert1 (cdr (assoc 10 bpoli2)))
            (setq p (car vert))
            (setq p1 (car vert1))
            (if (/= p p1)
                (progn
                (command "text" pause "1.5" "90" (car vert))
                (command "text" pause "1.5" "90" (cadr vert))
                )
            )                  
            (setq spoli  (entnext spoli))
            (setq poli2  (entnext poli2) bpoli (entget spoli) bpoli2 (entget poli2))
     );wh
)
(princ "\n Iniciar Rutina que recorre un pol�*gono:rpoli")

 

This meaning having done rpoli first and then dpoli, however, spoli is only the identifier of the entity, so, when I run dpoli, it doesn't find any changes because it goes through the data base of the entity as it is now, which is modified, this meaning database poli1=poli2=spoli, and I want it so Database poli1=poli2/=spoli with spoli the modified polyline and poli1 and 2 the database of the old polyline. How can I save in a variable the whole database of the polyline before it is modified and then compare it with the entity as it is when it's modified?

Posted

Just to test the concept, I put this together - its not fool-proof, and probably won't work with undo, or when an object is erased.

 

(defun c:PolyChange nil
 (vl-load-com)
 ;; © Lee Mac 2010

 (  (lambda ( data mod can / react objLst )
      (if (setq react
            (vl-some
              (function
                (lambda ( reactor )
                  (if (eq data (vlr-data reactor)) reactor)
                )
              )
              (cdar
                (vlr-reactors :vlr-object-reactor)
              )
            )
          )
        (if (vlr-added-p react)
          (progn
            (vlr-remove react)
            (setq *PolyData* nil)
          )
          (vlr-add react)
        )
        (setq react
          (vlr-object-reactor
            (progn
              (setq *PolyData*
                (mapcar
                  (function
                    (lambda ( obj )
                      (cons (vla-get-Handle obj)
                        (LM:Variant->2DPoints
                          (vla-get-Coordinates obj)
                        )
                      )
                    )
                  )
                  (setq objLst
                    (LM:ss->vla
                      (ssget "_:L" '((0 . "LWPOLYLINE")))
                    )
                  )
                )
              )
              objLst
            )
            data
            (list
              (cons :vlr-modified  mod)
              (cons :vlr-cancelled can)
            )
          )
        )
      )
      (princ
        (if (vlr-added-p react)
          "\n** Reactor Activated **"
          "\n** Reactor Deactivated **"
        )
      )
      react
    )
   "Example-Reactor"
   'PolyChange-Mod
   'PolyChange-Can
 )

 (princ)
)

(defun PolyChange-Mod ( object reactor args / points verts hand )
 (vl-load-com)
 
 (if *CommandisCancelled*
   (setq *CommandisCancelled* nil)    
   
   (if (and (not (vlax-erased-p object))
            (setq points (cdr (assoc (setq hand (vla-get-Handle object)) *PolyData*))))
     (progn      
       (mapcar
         (function
           (lambda ( p q )
             (or (equal p q 1e-6)
               (entmakex (list (cons 0 "POINT") (cons 10 p)))
             )
           )
         )
         (setq verts (LM:Variant->2DPoints (vla-get-Coordinates object)))
         points
       )
       (setq *PolyData*
         (subst (cons hand verts) (assoc hand *PolyData*) *PolyData*)
       )
     )
   )
 )
 (princ)
)
     
(defun PolyChange-Can ( object reactor args )
 (setq *CommandisCancelled* t)
 (princ)
)

;;-------------------=={ Variant Value }==--------------------;;
;;                                                            ;;
;;  Converts a VLA Variant into native AutoLISP data types    ;;
;;------------------------------------------------------------;;
;;  Author: Lee McDonnell, 2010                               ;;
;;                                                            ;;
;;  Copyright © 2010 by Lee McDonnell, All Rights Reserved.   ;;
;;  Contact: Lee Mac @ TheSwamp.org, CADTutor.net             ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  value - VLA Variant to process                            ;;
;;------------------------------------------------------------;;
;;  Returns:  Data contained within variant                   ;;
;;------------------------------------------------------------;;

(defun LM:VariantValue ( value )
 ;; © Lee Mac 2010
 (cond
   ( (eq 'variant (type value))

     (LM:VariantValue (vlax-variant-value value))
   )
   ( (eq 'safearray (type value))

     (mapcar 'LM:VariantValue (vlax-safearray->list value))
   )
   ( value )
 )
)

;;-----------------=={ Group by Number }==--------------------;;
;;                                                            ;;
;;  Groups a list into a list of lists, each of length 'n'    ;;
;;------------------------------------------------------------;;
;;  Author: Lee McDonnell, 2010                               ;;
;;                                                            ;;
;;  Copyright © 2010 by Lee McDonnell, All Rights Reserved.   ;;
;;  Contact: Lee Mac @ TheSwamp.org, CADTutor.net             ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  l - List to process                                       ;;
;;  n - Number of elements by which to group                  ;;
;;------------------------------------------------------------;;
;;  Returns:  List of lists, each of length 'n'               ;;
;;------------------------------------------------------------;;

(defun LM:GroupByNum ( l n / a b )
 ;; © Lee Mac 2010
 (while l
   (
     (lambda ( i )
       (while (< 0 i)
         (setq a (cons (car l) a) l (cdr l) i (1- i))
       )
       (setq b (cons (reverse a) b) a nil)
     )
     n
   )
 )
 (reverse b)
)

;;----------------=={ Variant->2DPoints }==-------------------;;
;;                                                            ;;
;;  Converts a Variant of Double type to a list of 2D Points  ;;
;;------------------------------------------------------------;;
;;  Author: Lee McDonnell, 2010                               ;;
;;                                                            ;;
;;  Copyright © 2010 by Lee McDonnell, All Rights Reserved.   ;;
;;  Contact: Lee Mac @ TheSwamp.org, CADTutor.net             ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  var - VLA Variant                                         ;;
;;------------------------------------------------------------;;
;;  Returns:  List of 2D Points                               ;;
;;------------------------------------------------------------;;

(defun LM:Variant->2DPoints ( var )
 ;; © Lee Mac 2010
 (LM:GroupByNum (LM:VariantValue var) 2)
)

;;-----------------=={ SelectionSet -> VLA }==----------------;;
;;                                                            ;;
;;  Converts a SelectionSet to a list of VLA Objects          ;;
;;------------------------------------------------------------;;
;;  Author: Lee McDonnell, 2010                               ;;
;;                                                            ;;
;;  Copyright © 2010 by Lee McDonnell, All Rights Reserved.   ;;
;;  Contact: Lee Mac @ TheSwamp.org, CADTutor.net             ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  ss - Valid SelectionSet (Pickset)                         ;;
;;------------------------------------------------------------;;
;;  Returns:  List of VLA Objects                             ;;
;;------------------------------------------------------------;;

(defun LM:ss->vla ( ss )
 ;; © Lee Mac 2010
 (if ss
   (
     (lambda ( i / e l )
       (while (setq e (ssname ss (setq i (1+ i))))
         (setq l (cons (vlax-ename->vla-object e) l))
       )
       l
     )
     -1
   )
 )
)

 

Type 'PolyChange' to Activate the reactor, select the LWPoly's you want to monitor.

 

Then try modifying a poly, (change a grip or something). A Point should be created at the modified point.

 

Type 'PolyChange' again to deactivate the reactor.

Posted
Just to test the concept, I put this together - its not fool-proof, and probably won't work with undo, or when an object is erased.

 

(defun c:PolyChange nil
 (vl-load-com)
 ;; © Lee Mac 2010

 (  (lambda ( data mod can / react objLst )
      (if (setq react
            (vl-some
              (function
                (lambda ( reactor )
                  (if (eq data (vlr-data reactor)) reactor)
                )
              )
              (cdar
                (vlr-reactors :vlr-object-reactor)
              )
            )
          )
        (if (vlr-added-p react)
          (progn
            (vlr-remove react)
            (setq *PolyData* nil)
          )
          (vlr-add react)
        )
        (setq react
          (vlr-object-reactor
            (progn
              (setq *PolyData*
                (mapcar
                  (function
                    (lambda ( obj )
                      (cons (vla-get-Handle obj)
                        (LM:Variant->2DPoints
                          (vla-get-Coordinates obj)
                        )
                      )
                    )
                  )
                  (setq objLst
                    (LM:ss->vla
                      (ssget "_:L" '((0 . "LWPOLYLINE")))
                    )
                  )
                )
              )
              objLst
            )
            data
            (list
              (cons :vlr-modified  mod)
              (cons :vlr-cancelled can)
            )
          )
        )
      )
      (princ
        (if (vlr-added-p react)
          "\n** Reactor Activated **"
          "\n** Reactor Deactivated **"
        )
      )
      react
    )
   "Example-Reactor"
   'PolyChange-Mod
   'PolyChange-Can
 )

 (princ)
)

(defun PolyChange-Mod ( object reactor args / points verts hand )
 (vl-load-com)
 
 (if *CommandisCancelled*
   (setq *CommandisCancelled* nil)    
   
   (if (and (not (vlax-erased-p object))
            (setq points (cdr (assoc (setq hand (vla-get-Handle object)) *PolyData*))))
     (progn      
       (mapcar
         (function
           (lambda ( p q )
             (or (equal p q 1e-6)
               (entmakex (list (cons 0 "POINT") (cons 10 p)))
             )
           )
         )
         (setq verts (LM:Variant->2DPoints (vla-get-Coordinates object)))
         points
       )
       (setq *PolyData*
         (subst (cons hand verts) (assoc hand *PolyData*) *PolyData*)
       )
     )
   )
 )
 (princ)
)
     
(defun PolyChange-Can ( object reactor args )
 (setq *CommandisCancelled* t)
 (princ)
)

;;-------------------=={ Variant Value }==--------------------;;
;;                                                            ;;
;;  Converts a VLA Variant into native AutoLISP data types    ;;
;;------------------------------------------------------------;;
;;  Author: Lee McDonnell, 2010                               ;;
;;                                                            ;;
;;  Copyright © 2010 by Lee McDonnell, All Rights Reserved.   ;;
;;  Contact: Lee Mac @ TheSwamp.org, CADTutor.net             ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  value - VLA Variant to process                            ;;
;;------------------------------------------------------------;;
;;  Returns:  Data contained within variant                   ;;
;;------------------------------------------------------------;;

(defun LM:VariantValue ( value )
 ;; © Lee Mac 2010
 (cond
   ( (eq 'variant (type value))

     (LM:VariantValue (vlax-variant-value value))
   )
   ( (eq 'safearray (type value))

     (mapcar 'LM:VariantValue (vlax-safearray->list value))
   )
   ( value )
 )
)

;;-----------------=={ Group by Number }==--------------------;;
;;                                                            ;;
;;  Groups a list into a list of lists, each of length 'n'    ;;
;;------------------------------------------------------------;;
;;  Author: Lee McDonnell, 2010                               ;;
;;                                                            ;;
;;  Copyright © 2010 by Lee McDonnell, All Rights Reserved.   ;;
;;  Contact: Lee Mac @ TheSwamp.org, CADTutor.net             ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  l - List to process                                       ;;
;;  n - Number of elements by which to group                  ;;
;;------------------------------------------------------------;;
;;  Returns:  List of lists, each of length 'n'               ;;
;;------------------------------------------------------------;;

(defun LM:GroupByNum ( l n / a b )
 ;; © Lee Mac 2010
 (while l
   (
     (lambda ( i )
       (while (< 0 i)
         (setq a (cons (car l) a) l (cdr l) i (1- i))
       )
       (setq b (cons (reverse a) b) a nil)
     )
     n
   )
 )
 (reverse b)
)

;;----------------=={ Variant->2DPoints }==-------------------;;
;;                                                            ;;
;;  Converts a Variant of Double type to a list of 2D Points  ;;
;;------------------------------------------------------------;;
;;  Author: Lee McDonnell, 2010                               ;;
;;                                                            ;;
;;  Copyright © 2010 by Lee McDonnell, All Rights Reserved.   ;;
;;  Contact: Lee Mac @ TheSwamp.org, CADTutor.net             ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  var - VLA Variant                                         ;;
;;------------------------------------------------------------;;
;;  Returns:  List of 2D Points                               ;;
;;------------------------------------------------------------;;

(defun LM:Variant->2DPoints ( var )
 ;; © Lee Mac 2010
 (LM:GroupByNum (LM:VariantValue var) 2)
)

;;-----------------=={ SelectionSet -> VLA }==----------------;;
;;                                                            ;;
;;  Converts a SelectionSet to a list of VLA Objects          ;;
;;------------------------------------------------------------;;
;;  Author: Lee McDonnell, 2010                               ;;
;;                                                            ;;
;;  Copyright © 2010 by Lee McDonnell, All Rights Reserved.   ;;
;;  Contact: Lee Mac @ TheSwamp.org, CADTutor.net             ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  ss - Valid SelectionSet (Pickset)                         ;;
;;------------------------------------------------------------;;
;;  Returns:  List of VLA Objects                             ;;
;;------------------------------------------------------------;;

(defun LM:ss->vla ( ss )
 ;; © Lee Mac 2010
 (if ss
   (
     (lambda ( i / e l )
       (while (setq e (ssname ss (setq i (1+ i))))
         (setq l (cons (vlax-ename->vla-object e) l))
       )
       l
     )
     -1
   )
 )
)

Type 'PolyChange' to Activate the reactor, select the LWPoly's you want to monitor.

 

Then try modifying a poly, (change a grip or something). A Point should be created at the modified point.

 

Type 'PolyChange' again to deactivate the reactor.

 

Wow... a lot of commands I don't know. Thank you very much, gonna study it and see how to make it work for me.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...