Jump to content

Improved Break LISP routine


broncos15

Recommended Posts

I have a quick question on my lisp routine that is trying to combine the break feature line and break command into one command. I am new to Visual Lisp and Auto Lisp, so I was unsure if it has an else if statement like VBA (I would prefer to use the else if for the break command). My code is below and is currently not working, so I am pretty sure that I am doing something stupid. I am assuming that my mistake is in the if statement, but I am not sure how to fix it. I created the code by combining two of my routines for breaking objects.

 

(defun c:break2 ( / ent)
(setq ent (entsel "\nSelect Object: ")); Has user select object
(if
     (and ent (= "Pline" ))
 (princ "Break Point")
 (command "_.break" pause "_f")
  (princ "\nBreak point: ")
  (command pause "@")
  )
(if
     (and ent (= "Feature Line" ))
(princ "._AeccBreakFeatures")
(command "_.break" pause "_f")
 (princ "\nBreak point: ")
 (command pause "@")
 )
(princ)
)

Edited by broncos15
Link to comment
Share on other sites

Start here:

 

(defun c:break2 ( / ent)
(setq ent (car (entsel "\nSelect Object: "))); Has user select object
(if (= (setq enttype (cdr (assoc 0 (entget ent)))) "LWPOLYLINE")
  (progn
 (princ "Break Point")
 (command "_.break" pause "_f")
  (princ "\nBreak point: ")
  (command pause "@")
  )
(if (= enttype "AECC_FEATURE_LINE")
(princ "._AeccBreakFeatures")
(command "_.break" pause "_f")
 (princ "\nBreak point: ")
 (command pause "@")
 )
  )
(princ)
)

Link to comment
Share on other sites

Start here:

 

(defun c:break2 ( / ent)
(setq ent (car (entsel "\nSelect Object: "))); Has user select object
(if (= (setq enttype (cdr (assoc 0 (entget ent)))) "LWPOLYLINE")
  (progn
 (princ "Break Point")
 (command "_.break" pause "_f")
  (princ "\nBreak point: ")
  (command pause "@")
  )
(if (= enttype "AECC_FEATURE_LINE")
(princ "._AeccBreakFeatures")
(command "_.break" pause "_f")
 (princ "\nBreak point: ")
 (command pause "@")
 )
  )
(princ)
)

 

Thank you so much for the help! I am getting a syntax error when running it unfortunately. I had a few quick questions about how it works because I want to understand it.

1) What doe the "car" and cdr portion of (if (= (setq enttype (cdr (assoc 0 (entget ent)))) "LWPOLYLINE") do exactly?

2) Why does there need to be the (=enttype for the second portion of the code, but not the first?

3) How do I debug a code when it doesn't even load it (tried using vlide, but it says that there are to many arguments)?

Edited by broncos15
Link to comment
Share on other sites

broncos15,

 

(entget ent) returns the whole dxfcode list for entity ent.

(assoc 0 (entget ent)) returns an association list of the form (0 . "LWPOLYLINE) or whatever type of entity you've selected.

So (cdr (0 . "LWPOLYLINE")) returns you only the "LWPOLYLINE"

 

You need to get acquainted with the dxfcode of entities. An entsel simply returns the entityname (actually simply a number).

The entget gives you the list of every details about the entities.

 

ymg

Link to comment
Share on other sites

broncos15,

 

(entget ent) returns the whole dxfcode list for entity ent.

(assoc 0 (entget ent)) returns an association list of the form (0 . "LWPOLYLINE) or whatever type of entity you've selected.

So (cdr (0 . "LWPOLYLINE")) returns you only the "LWPOLYLINE"

 

You need to get acquainted with the dxfcode of entities. An entsel simply returns the entityname (actually simply a number).

The entget gives you the list of every details about the entities.

 

ymg

 

 

Thanks for the information, that is good to know. If I understand correctly, entget is a much more powerful function, especially for if statements because it returns the specific type of entity that was selected? Also, within an if statement for LISP, are you able to include multiple entities like VBA (ie if "LWPOLYLINE" "LINE" "ARC"), etc. or do you have to make separate if statements for each different type of entity?

Link to comment
Share on other sites

So I made a few changes to the code, so that I could incorporate all the functions of break (I decided to switch it to a conditional statement instead of an if), but I am still having some issues. The code runs, allows me to select an object, and then it has a few quinks.1) It makes me select the object again if it is a pline and then it says error: bad function: T. It does break it however. It won't work at all if it is a feature line however.

(defun c:break2 ( / ent)
(setq ent (car (entsel "\nSelect Object: "))); Has user select object
 (cond (= enttype "AECC_FEATURE_LINE")
(princ "._AeccBreakFeatures")
(command "_.break" pause "_f")
 (princ "\nBreak point: ")
 (command pause "@")
 )
 (t   
 (princ "Break Point")
 (command "_.break" pause "_f")
  (princ "\nBreak point: ")
  (command pause "@")
  ) 
 )
(princ)
)

Edited by broncos15
Forgot parenthesis
Link to comment
Share on other sites

brocos15,

 

The last code you are showing cannot work.

 

Where do you get the value for enttype ???

 

Also in your example, I don't see the need for a conditionnal test

as both case execute the very same command.

 

Only difference for one you princ the type of the object you selected.

 

To get the type you will need the (cdr (assoc 0 (entget ent))) statement.

 

Also, if you inspect the return of the (entsel) statement, you will see that

you get a list of 2 items. The first one is the entity name (Do not confuse it with the entity type),

the second is the point where you picked the entity.

 

So you could come up with a way to effect your break with a single pick if you set your osnap.

 

ymg

Link to comment
Share on other sites

In my Line Object Menu under Shortcut Menus in the CUI I added the Macro:

Name: Break Line @

Macro: ^C^C^P(setq ss (ssget))(command "_break" ss);\@;^C^C^P(progn(setq ss nil)(princ))

 

It's included in my LWPline Object Menu & Arc Object Menu as well.

So with a line, polyline, or arc I can select, right-click, select Break Line @, then pick break point. If you have lines on top of each other picking the right one with (entsel) can be difficult.

Link to comment
Share on other sites

broncos15 do a little bit of home work about DXF codes these are the ones used with assoc and entmake, the alternative is to use VLlisp and you can get properties via a name eg "assoc 8" is a layer name Vl use "get-Layer"

 

car cadr caddr cadddr and so on (8 . "layer2") car = 8, cadr = "Layer2" (123.45 678.90) car 123.45, cadr 678.90

 

A simple dxf code example (princ (entget (car (entsel)))) pick various objects have a look at all the info some will be obvious

Link to comment
Share on other sites

try this :-

 

(defun c:brk (/ a b)
 (if (setq a (car (entsel "\nSelect Object : ")))
   (progn
     (setq b (cdr (assoc 0 (entget a))))
     (cond ((eq b "LWPOLYLINE")
     (command "_.break" a pause "@")
    )
    [color="red"][b]([/b][/color]t (command "_.break" a pause "@")[color="red"][b])[/b][/color] [b][color="blue"]; edit here as per your requirement[/color][/b]
     )
   )
 )
 (princ)
)

Link to comment
Share on other sites

  • 5 months later...
try this :-

 

(defun c:brk (/ a b)
 (if (setq a (car (entsel "\nSelect Object : ")))
   (progn
     (setq b (cdr (assoc 0 (entget a))))
     (cond ((eq b "LWPOLYLINE")
     (command "_.break" a pause "@")
    )
    [color="red"][b]([/b][/color]t (command "_.break" a pause "@")[color="red"][b])[/b][/color] [b][color="blue"]; edit here as per your requirement[/color][/b]
     )
   )
 )
 (princ)
)

I am still getting some errors when I am running my current code, saying that I have to many arguments, but I can't figure out why. My new code is:
(defun c:breakfirst2 (/ *error* whilestop ent entlist pt)
 (defun *error* (msg)
   (if (not
         (member msg '("Function cancelled" "quit / exit abort"))
       )
     (princ (strcat "\nError: " msg))
   )
   (princ)
 )
 (setq whilestop t)
 (setvar 'errno 0)
 (while whilestop
   (if (setq ent (car (entsel "\nSelect object to break: ")))
     (progn
       (setq entlist (entget ent))
       (cond
         ((/= (or (cdr (assoc 0 entlist) "LINE")
                  (cdr (assoc 0 entlist) "ARC")
                  (cdr (assoc 0 entlist) "CIRCLE")
                  (cdr (assoc 0 entlist) "POLYLINE")
                  (cdr (assoc 0 entlist) "AECC_FEATURE_LINE")
              )
          )
          (princ "\nNot a valid object, try again.")
         )
         ((= (cdr (assoc 0 entlist) "AECC_FEATURE_LINE"))
          (if (setq pt (getpoint "\nSelect break point: "))
            (progn
              (command "._AeccBreakFeatures" ent "_f" pt)
              (setq whilestop nil)
            )
          )
         )
         (t
          (if (setq pt (getpoint "\nSelect break point: "))
            (progn
              (command "._Break" ent "_f" pt)
              (setq whilestop nil)
            )
          )
         )
       )
     )
   )
   (if (/= (getvar 'errno) 52)
     (princ "\nYou missed. Try again.")
     (setq whilestop nil)
   )
 )
)

Link to comment
Share on other sites

On first glance:

(cdr (assoc 0 entlist) "LINE")

should be perhaps:

[highlight](=[/highlight] (cdr (assoc 0 entlist)[highlight])[/highlight] "LINE")

And the same for the other expressions.

Link to comment
Share on other sites

Here's a quick rework of your code to get you going:

(defun c:breakfirst2 ( / *error* ent pnt stop typ )

   (defun *error* ( msg )
       (if (not (member msg '("Function cancelled" "quit / exit abort")))
           (princ (strcat "\nError: " msg))
       )
       (princ)
   )

   (while (not stop)
       (setvar 'errno 0)
       (setq ent (entsel "\nSelect object to break: "))
       (cond
           (   (= 52 (getvar 'errno))
               (setq stop t)
           )
           (   (null ent)
               (princ "\nYou missed. Try again.")
           )
           (   (not (wcmatch (setq typ (cdr (assoc 0 (entget (car ent))))) "LINE,ARC,CIRCLE,POLYLINE,AECC_FEATURE_LINE"))
               (princ "\nNot a valid object, try again.")
           )
           (   (not (setq pnt (getpoint "\nSelect break point: ")))
               (setq stop t)
           )
           (   (= typ "AECC_FEATURE_LINE")
               (command "_.aeccbreakfeatures" ent "_f" "_non" pnt "_non" pnt)
               (setq stop t)
           )
           (   t
               (command "_.break" ent "_f" "_non" pnt "_non" pnt)
               (setq stop t)
           )
       )
   )
   (princ)
)

Link to comment
Share on other sites

Great code, Lee! I tweaked it abit (for my prefers)

(defun c:breakfirst2 ( / *error* ent pnt stop typ )

   (defun *error* ( msg )
       (if (not (member msg '("Function cancelled" "quit / exit abort")))
           (princ (strcat "\nError: " msg))
       )
       (princ)
   )

   (while (not stop)
       (setvar 'errno 0)
       (setq ent (entsel "\nSelect object to break: "))
       (cond
           (   (= 52 (getvar 'errno))
               (setq stop t)
           )
           (   (null ent)
               (princ "\nYou missed. Try again.")
           )
           (   (not (wcmatch (setq typ (cdr (assoc 0 (entget (car ent))))) "LINE,XLINE,RAY,LWPOLYLINE,ARC,CIRCLE,POLYLINE,AECC_FEATURE_LINE"))
               (princ "\nNot a valid object, try again.")
           )
           (   (not (setq pnt (getpoint "\nSelect break point: ")))
               (setq stop t)
           )
           (   (= typ "AECC_FEATURE_LINE")
               (command "_.aeccbreakfeatures" ent "_f" "_non" pnt "_non" pnt)
               (setq stop t)
           )
           (   t
               (while (command "_.break" ent "_f" "_non" pnt "_non" pnt)
               (setq stop t))
           )
       )
   )
   (princ)
)

Link to comment
Share on other sites

Thank you Lee and Grr, I really appreciate the help! I ended up rewriting it just a bit to get some more code practice. My code is

(defun c:breakfirst2 (/ *error* whilestop ent entlist pt)
 (defun *error* (msg)
   (if (not
         (member msg '("Function cancelled" "quit / exit abort"))
       )
     (princ (strcat "\nError: " msg))
   )
   (princ)
 )
 (setq whilestop t)
 (while whilestop
   (setvar 'errno 0)
   (setq ent (entsel "\nSelect object to break: "))
   (cond
     ((= 52 (getvar 'errno))
      (setq whilestop nil)
     )
     ((null ent)
      (princ "\nYou missed. Try again.")
     )
     ((not (wcmatch (setq typ (cdr (assoc 0 (entget (car ent)))))
                    "LINE,ARC,CIRCLE,LWPOLYLINE,POLYLINE,RAY,XLINE,AECC_FEATURE_LINE"
           )
      )
      (princ "\nNot a valid object, try again.")
     )
     ((not (setq pt (getpoint "\nSelect break point: ")))
      (setq whilestop nil)
     )
     ((= typ "AECC_FEATURE_LINE")
      (vl-cmdf "._AeccBreakFeatures" ent "_f" "_non" pt "_non" pt)
      (setq whilestop nil)
     )
     (t
      (vl-cmdf "_.break" ent "_f" "_non" pt "_non" pt)
      (setq whilestop nil)
     )
   )
 )
 (princ)
)

What's strange is that both of your codes and mine do not work on the feature lines. There seems to be some glitch with the aeccbreakfeatures command. A code I wrote that does work is

(defun C:Breakfeaturesfirst ()
 (princ "Break feature lines at point")
 (command "._AeccBreakFeatures" pause "_f")
 (princ "\nBreak point: ")
 (command pause "@")
 (princ)
)

Is there an easy way to incorporate the code that does work in the while loop? I don't want the user to have to hit a point twice because that not getpoint statement is in there. Also, if the user is breaking a feature line and hits escape with my breakfeaturesfirst code inserted into the breakfirst2 code, then it cause the code to break. Any suggestions?

Link to comment
Share on other sites

So here is the new and improved code that works perfectly. I figured that I would post it for anyone that wants it in the future. Thanks again Lee and Grrr for the help!

;;;Created by Broncos15 on 2/18/16
;;;Had help from Lee Mac and Grrr
(defun c:breakfirst (/ *error* whilestop ent entlist pt)
 (defun *error* (msg)
   (if (not
         (member msg '("Function cancelled" "quit / exit abort"))
       )
     (princ (strcat "\nError: " msg))
   )
   (princ)
 )
 (setq whilestop t)
 (while whilestop
   (setvar 'errno 0)
   (setq ent (entsel "\nSelect object to break: "))
   (cond
     ((= 52 (getvar 'errno))
      (setq whilestop nil)
     )
     ((null ent)
      (princ "\nYou missed. Try again.")
     )
     ((not (wcmatch (setq typ (cdr (assoc 0 (entget (car ent)))))
                    "LINE,ARC,CIRCLE,LWPOLYLINE,POLYLINE,RAY,XLINE,AECC_FEATURE_LINE"
           )
      )
      (princ "\nNot a valid object, try again.")
     )
     ((= typ "AECC_FEATURE_LINE")
      (command "._AeccBreakFeatures" ent "_f")
      (princ "\nPick break point: ")
      (command pause "@")
      (setq whilestop nil)
     )
     ((setq pt (getpoint "\nPick break point: "))
      (vl-cmdf "_.break" ent "_f" "_non" pt "_non" pt)
      (setq whilestop nil)
     )
     (t
      (setq whilestop nil)
     )
   )
 )
 (princ)
)

Link to comment
Share on other sites

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...