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

LISP Routine to delete entities from selection using SSDEL

17 REPLIES 17
SOLVED
Reply
Message 1 of 18
Matul
4784 Views, 17 Replies

LISP Routine to delete entities from selection using SSDEL

Hello,

 

I am trying to get a lisp to work but am having some trouble using the SSDEL function. Please see code below. What I am trying to do is create a layer if it doesn't exist, have user select objects on screen, move to newly created layer and THEN remove all circles from the selection set before converting to polylines. I cannot get the ssdel function to work and I keep getting the following message:

no function definition: _KPBLC-LAYER-STATUS-RESTORE

 

Not sure if I need to use different syntax or and IF statement with the ssdel callout but it doesn't seem to work for me. Any help would be greately appreciated.

 

(defun c:mped (/ ent n name ss1 etype ssetCircles)
(if (not (tblsearch "layer" "BORDER"))
(command "layer" "m" "BORDER" "lt" "" "" "c" "1" "" ""))

(princ "\nSelect objects to move to the BORDER layer and convert to polylines...")
(setq ss1 (ssget '((0 . "CIRCLE,ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE"))))
(setq nlayer "BORDER")
(command "chprop" ss1 "" "LA" nlayer "c" "BYLAYER" "")
(setq ss1 (ssdel "CIRCLE" ss1))
;(ssdel ss1 (0. "CIRCLE"))

(command " " "_.pedit" "_m" ss1 "" "Y" "_J" "0.001" "")
(setvar "clayer" "0")

(princ "Entities have been moved to BORDER layer and converted to single polyline")
(princ)
) ;end MPed

 

The reason I am removing them from the selection is due to the circles not being able to convert to polylines and causing issues with the lisp. If there are other ways to get around this I would welcome other suggestions as well. 


Thank you!

Tags (1)
17 REPLIES 17
Message 2 of 18
Shneuph
in reply to: Matul

ssdel needs to be passed an entity name (to be removed) and a selection set (to remove it from).

ssdel Help

 

What about repeating:

(setq ss1 (ssget '((0 . "ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE"))))

 

removing the object types you do not want to have in the selection set.

 

You may have to remove splines and ellipsis as well.

Message 3 of 18
Matul
in reply to: Shneuph

But that would require an additional user input which is what I am trying to avoid. Is it possible to loop through SS1 and establish the selection set to remove?

Thank you

Message 4 of 18
dbroad
in reply to: Matul

1. The error you are getting, "no function definition: _KPBLC-LAYER-STATUS-RESTORE", has nothing to do with ssdel.

2. As the other poster stated, you must use enames with ssdel, not entity types.

 

You don't need to filter out circles though anyway, since mpedit will simply ignore circles.  This should work fine. I also put the nlayer setq first so that it could be used throughout.

 

 

(defun c:test ( / ss1 nlayer)
  (setq nlayer "BORDER")
  (if (not (tblsearch "layer" NLAYER))
    (command "layer" "m" NLAYER "lt" "" "" "c" "1" "" "")
  )
  (princ
    "\nSelect objects to move to the BORDER layer and convert to polylines..."
  )
  (setq	ss1
	 (ssget
	   '((0 . "CIRCLE,ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE"))
	 )
  )
  (command "chprop" ss1 "" "LA" nlayer "c" "BYLAYER" "")
  (command " " "_.pedit" "_m" ss1 "" "Y" "_J" "0.001" "")
  (setvar "clayer" "0")
  (princ (strcat "Entities have been moved to "
		 nlayer
		 " layer and converted to single polyline"
	 )
  )
  (princ)
)					;end test

 

To filter a type from a selection set, you could  loop through as follows:

(repeat (setq i (sslength ss1))
  (SETQ i (1- i))
  (if (= "CIRCLE" (CDR(ASSOC 0 (ENTGET (setq e (ssname ss1 i))))))
    (SSDEL e SS1 ))
  )

 

 

 

Architect, Registered NC, VA, SC, & GA.
Message 5 of 18
Shneuph
in reply to: Shneuph

yes you can loop through and use ssname to get entity names and check the entity type..

 

(setq n 1)
  (repeat (sslength ss1)
    (if (= (cdr (assoc 0 (entget (ssname ss1 n)))) "CIRCLE")
      (setq ss1 (ssdel (ssname ss1 n) ss1))
      );if
    (setq n (1+ n))
    );repeat
  (princ)

 

Message 6 of 18
Matul
in reply to: dbroad

The lisp does work and it ignore circles - the problem that I am having is that if ONLY circles are initially selected it starts asking users for input such as SELECT POLYLINE or MULTIPLE. So I guess what I really need is for the lisp to use the PEDIT line on entities that can be converted and jump over that line for entities that it will not work with such as CIRCLES. So if no available entities exist for the PEDIT line it should skip it. 

Thank you

Message 7 of 18
Kent1Cooper
in reply to: Matul

I think your error may be from the " " before the PEDIT command, which is probably recalling the last command entered outside the routine.

 

If you really want to omit Circles from consideration by PEDIT, even if as dbroad says it will ignore them, you can have it do that by treating everything that isn't a Circle, using the tilde ~ wildcard code for "not-what-follows":

....

(setq ss1 (ssget '((0 . "CIRCLE,ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE"))))
(setq nlayer "BORDER")
(command

  "chprop" ss1 "" "LA" nlayer "c" "BYLAYER" ""
  "_.pedit" "_m" (ssget "_P" '((0 . "~CIRCLE"))) "" "Y" "_J" "0.001" "" ;; without the " " preceding

); command

....

Kent Cooper, AIA
Message 8 of 18
Kent1Cooper
in reply to: Matul


@Matul wrote:

.... if ONLY circles are initially selected it starts asking users for input such as SELECT POLYLINE or MULTIPLE. So I guess what I really need is for the lisp to use the PEDIT line on entities that can be converted and jump over that line for entities that it will not work with such as CIRCLES. So if no available entities exist for the PEDIT line it should skip it. 

....


In that case, something like [untested]:

....

(setq ss1 (ssget '((0 . "CIRCLE,ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE"))))
(setq nlayer "BORDER")
(command "chprop" ss1 "" "LA" nlayer "c" "BYLAYER" "")

(if (setq noCirc  (ssget "_P" '((0 . "~CIRCLE")))) ;; only if there are other-than-Circle objects
  (command "_.pedit" "_m" noCirc "" "Y" "_J" "0.001" ""); then ;; without the " " preceding

); if

....

Kent Cooper, AIA
Message 9 of 18
dbroad
in reply to: Shneuph

Shneuph,

There are a couple of problems with your code.  Selection sets have a 0 index, meaning that the first element is the 0th element.  So n=1 as a starting point would skip the first element.  Secondly, if objects are deleted from a selection set, it affects the indexing of the selection set so that incrementing the index would likely lead to an out of bounds issue or would skip elements.  If you start from the sslength-1 and then decrement the counter, both of those problems disappear.  See my example above.

Architect, Registered NC, VA, SC, & GA.
Message 10 of 18
dbroad
in reply to: Matul


@Matul wrote:

 So if no available entities exist for the PEDIT line it should skip it. 


Using my previous test code, just put the pedit command inside an if statement (or use Kent's previous selection set filter).

(defun c:test ( / ss1 nlayer i e)
  (setq nlayer "BORDER")
  (if (not (tblsearch "layer" NLAYER))
    (command "layer" "m" NLAYER "lt" "" "" "c" "1" "" "")
  )
  (princ
    "\nSelect objects to move to the BORDER layer and convert to polylines..."
  )
  (setq	ss1
	 (ssget
	   '((0 . "CIRCLE,ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE"))
	 )
  )
  (command "chprop" ss1 "" "LA" nlayer "c" "BYLAYER" "")
  (repeat (setq i (sslength ss1))
  (SETQ i (1- i))
  (if (= "CIRCLE" (CDR(ASSOC 0 (ENTGET (setq e (ssname ss1 i))))))
    (SSDEL e SS1 ))
  )
  (if (and ss1 (> (sslength ss1) 0))
    (command " " "_.pedit" "_m" ss1 "" "Y" "_J" "0.001" ""))
  (setvar "clayer" "0")
  (princ (strcat "Entities have been moved to "
		 nlayer
		 " layer and converted to polyline(s) where possible."
	 )
  )
  (princ)
)					;end test

 

Architect, Registered NC, VA, SC, & GA.
Message 11 of 18
Matul
in reply to: Kent1Cooper

Kent and dbroad,

Both your answers combined did the trick. Thank you! I haven't ran into any problems so far with these changes. I really appreciate the very prompt help!

Message 12 of 18
bradlyferrell
in reply to: Matul

Matul unfortunately did not post the finished (working) code.

I have been struggling trying to figure out how he 'combined' the 2 suggestions from Kent & dbroad to get this to work.

 

Similar to Matul, I simply need the pedit command to be 'skipped over' if the ONLY thing found is a CIRCLE.

 

The selection set IS created (in the event there are other entities), the circle is removed from the ss, but then the pedit command still tries to run...which prompts the user to select something because the ss1 is empty (0 or nil).

 

This is what I have:

 

(setq ss1 (ssget '((0 . "CIRCLE,ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE"))))
(repeat (setq i (sslength ss1))
  (SETQ i (1- i))
  (if (= "CIRCLE" (CDR(ASSOC 0 (ENTGET (setq e (ssname ss1 i))))))
    (SSDEL e SS1)))
  (if (and ss1 (> (sslength ss1) 0))
    (command " " "_.pedit" "_m" ss1 "" "Y" "_J" "0.001" ""))

 

(setq ss1 nil)

(PRINC)

 

 

Also, is there a way to just use something like this nested within an IF statement as well as the loop to remove the circle and/or skip pedit command if only a circle is present?:

(setq ss1 (ssget "_x")) ;filters needed here

(command "_pedit" "m" ss1 "" "j" "" "")

 

 

I know I am close but cannot get it to 'skip over' the command.

Any help would be greatly appreciated! Thank you!!

Message 13 of 18
Kent1Cooper
in reply to: bradlyferrell


@bradlyferrell wrote:

.... 

Similar to Matul, I simply need the pedit command to be 'skipped over' if the ONLY thing found is a CIRCLE.

 

The selection set IS created (in the event there are other entities), the circle is removed from the ss, but then the pedit command still tries to run...which prompts the user to select something because the ss1 is empty (0 or nil).

 

This is what I have:

 

(setq ss1 (ssget '((0 . "CIRCLE,ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE"))))
(repeat (setq i (sslength ss1))
  (SETQ i (1- i))
  (if (= "CIRCLE" (CDR(ASSOC 0 (ENTGET (setq e (ssname ss1 i))))))
    (SSDEL e SS1)))
  (if (and ss1 (> (sslength ss1) 0))
    (command " " "_.pedit" "_m" ss1 "" "Y" "_J" "0.001" ""))

 

(setq ss1 nil)

(PRINC)

 

Also, is there a way to just use something like this nested within an IF statement as well as the loop to remove the circle and/or skip pedit command if only a circle is present?:

(setq ss1 (ssget "_x")) ;filters needed here

(command "_pedit" "m" ss1 "" "j" "" "")

....


You still have the extraneous " " before the "_.pedit" command name that I warned about in Post 7 [Doug didn't remove that in his suggestions, but it needs to go].  And you still have removal of Circles from ss1 in a way that will throw off the stepping through using the 'i' index variable, that Doug warned about in Post 9.

 

In place of the what-you-have above, I would think you could use my suggestion in Post 8 directly, leaving out the two Layer-related lines if you like, which does the skipping of the PEDIT command if the selection includes nothing but Circles:

 

(setq ss1 (ssget '((0 . "CIRCLE,ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE"))))
(if (setq noCirc (ssget "_P" '((0 . "~CIRCLE")))) ;; only if there are other-than-Circle objects
  (command "_.pedit" "_m" noCirc "" "Y" "_J" "0.001" ""); then ;; without the " " preceding
); if

 

But are you, like Matul, also using the selection set including Circles for something else, in addition to using it without Circles for PEDITing?  If you're not, of course you can just omit CIRCLE from the initial (ssget) filter list, and avoid the issue.

 

EDIT:  And another thing:  That assumes that you have the PEDITACCEPT System Variable set to 0, and that it will ask you whether to convert Lines and Arcs into Polylines -- that's what the "Y" is there to answer.  If the selection happens to consist of nothing other than already-Polylines, PEDIT won't ask that question, so the "Y" will cause trouble.  To avoid that possibility, set PEDITACCEPT to 1 [within the code if you like] so that it won't ask, and remove the "Y".

Kent Cooper, AIA
Message 14 of 18
bradlyferrell
in reply to: Kent1Cooper

Thank you for the quick response Kent!

 

No, once the pedit command has run...or not in the case there are only cirlces...I have no other use for the selection set.

 

I have used your last suggestion and it is still not 'skipping over' the pedit command. It just stops and waits for a manual selection input.

 

To be clear, the selection set could initially have lines, ellipses and cirlces.

I just want to exclude the circles so that everything else will poly/join.

Sometimes, only a circle is within the selection set (no other line work), so it needs to skip the pedit command altogether.

It is still not doing that when I use the (ssget '((0 . {filter-list} method.

 

It seems that (setq ss1 (ssget "_x")) seems to be more 'friendly' for some reason, but I cannot get the circles removed from the ss when placing it within an IF statement.

 

Here is the whole routine for reference:

 

;|
CREATES A PLASMA FILE FOR CNC BURN TABLE
USE COPYBASE COMMAND - OPEN NEW DWG - TYPE "PLA" - SAVE & CLOSE FILE
|;


(defun c:pla (/ ob lw ss1)

(initerr)      ;intit error-global error trap

(setvar "CLAYER" "0")
(command ".pasteclip" "0,0,0")
(command "Zoom" "E" "Zoom" "0.95x")
(PRINC)
(Command "-purge" "all" "" "no")
(PRINC)

(setq ob (ssget "_X" '((8 . "Hidden (ANSI)"))))
(command "erase" ob "")
(setq ob nil)
(PRINC)

(setq ob (ssget "_x"))
;(setvar "qaflags" 1)
(command "chprop" ob "" "LA" "0" "Color" "White" "Ltype" "Continuous" "")
;(setvar "qaflags" 2)
(setq ob nil)
(PRINC)

(Command "-overkill" "All" "" "");REMOVES/COMBINES ANY DOUBLE LINES/CURVES/ETC
(PRINC)

(Command "-purge" "all" "" "no")
(PRINC)

 

(setq ss1 (ssget '((0 . "CIRCLE,ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE"))))
(if (setq noCirc (ssget "_P" '((0 . "~CIRCLE")))) ;; only if there are other-than-Circle objects
  (command "_.pedit" "_m" noCirc "" "Y" "_J" "0.001" ""); then
); if


(PRINC)
(command ".regen")

(setq lw nil)

(PRINC)

(prompt "                                                                                                      OPERATION COMPLETE: SAVE FILE NOW")

(reset)  ;reset variables-global error trap

(PRINC)
);defun

Message 15 of 18
Kent1Cooper
in reply to: bradlyferrell


@bradlyferrell wrote:

.... 

No, once the pedit command has run...or not in the case there are only cirlces...I have no other use for the selection set.

 

I have used your last suggestion and it is still not 'skipping over' the pedit command. It just stops and waits for a manual selection input.

.... 

(setq ss1 (ssget '((0 . "CIRCLE,ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE"))))
(if (setq noCirc (ssget "_P" '((0 . "~CIRCLE")))) ;; only if there are other-than-Circle objects
  (command "_.pedit" "_m" noCirc "" "Y" "_J" "0.001" ""); then
); if

 

....

I expect [without loading it up and running it] that it's not waiting for PEDIT selection, but for (ssget) selection.  That (ssget) from Matul's process involves user selection, from which it will filter out anything not of the listed entity types.  If you want it to pick everything without user input [which seems likely, given the preceding operations], you need to include the "_X" before the filter list.

 

If that's what you need, but if you don't need that selection set for any other purpose, just grab everything eligible, leaving Circles out of it entirely:

(if (setq ss1 (ssget "_X" '((0 . "ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE")))) ;; CIRCLE removed
  (command "_.pedit" "_m" ss1 "" "Y" "_J" "0.001" ""); then
); if

 

But I still think that "Y" should be omitted, with PEDITACCEPT set to 1, for the reason explained before.

Kent Cooper, AIA
Message 16 of 18
bradlyferrell
in reply to: Kent1Cooper

VERY CLOSE! 🙂

 

This works:

(if (setq ss1 (ssget "_X" '((0 . "ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE")))) ;; CIRCLE removed
  (command "_.pedit" "_m" ss1 "" "_J" "0.001" ""); then
); if

 

Yes, the "Y" needed to be removed since PEDITACCEPT is indeed set to 1.

 

The only issue now is how pedit expects a different response when splines are present.

It requires a precision for the spline conversion, but it is not accounted for the way we have the command currently written.

 

I am thinking about how to go about checking for splines and then how to deal with the 'extra input' that is required.

I will keep working on it and any more help you might can provide is humbly welcomed!

 

 - Maybe poly/join all splines if present first, then run the pedit command you correctly provided in the last post (minus SPLINE in the filter)??

Message 17 of 18
Kent1Cooper
in reply to: bradlyferrell


@bradlyferrell wrote:

.... 

This works:

(if (setq ss1 (ssget "_X" '((0 . "ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE")))) ;; CIRCLE removed
  (command "_.pedit" "_m" ss1 "" "_J" "0.001" ""); then
); if

.... 

The only issue now is how pedit expects a different response when splines are present.

It requires a precision for the spline conversion, but it is not accounted for the way we have the command currently written.

.... 

 - Maybe poly/join all splines if present first, then run the pedit command you correctly provided in the last post (minus SPLINE in the filter)??


Since I'm currently at my location with an older AutoCAD that won't accept Splines at all in PEDIT, I can't check, but that last sounds like as good an approach as any.  Or you could do something like:

 

(if (setq ss1 (ssget "_X" '((0 . "ELLIPSE,SPLINE,LWPOLYLINE,POLYLINE,ARC,LINE"))))

  (if (ssget "_P" '((0 . "SPLINE"))); contains any of those?

    (command "_.pedit" "_m" ss1 "" .... with appropriate additional prompt response(s) related to Spline(s) .... ); then
    (command "_.pedit" "_m" ss1 "" "_J" "0.001" ""); else [no Spline(s)]

  ); if
); if

 

Kent Cooper, AIA
Message 18 of 18
bradlyferrell
in reply to: Kent1Cooper

Life is good again 🙂

 

Everything seems to be working fine now.
I didn't use your last suggestion but everything else has been a spectacular victory!

 

Thank you so much for your help Kent!!!

And thank you too for the "ellipse to pline" conversion (from another thread).

Now everything in the drawing is/are polylines which makes our CNC folks happy.

 

In the event someone else may need it for reference, here is the working code:

 

;CREATES A PLASMA FILE FOR CNC BURN TABLE
;USE COPYBASE COMMAND - OPEN NEW DWG - TYPE "PLA" - SAVE & CLOSE FILE

(defun c:pla (/ ob lw ss1 ss2 x)

(vl-load-com)

(initerr);intit error-global error trap

(setvar "CLAYER" "0")
(command ".pasteclip" "0,0,0")
(command "Zoom" "E" "Zoom" "0.95x")
(PRINC)
(Command "-purge" "all" "" "no")
(PRINC)

(setq ob (ssget "_X" '((8 . "Hidden (ANSI)"))))
(command "erase" ob "")

(setq ob nil); clear variable

(PRINC)

(setq ob (ssget "_x"))
;(setvar "qaflags" 1)
(command "chprop" ob "" "LA" "0" "Color" "White" "Ltype" "Continuous" "")
;(setvar "qaflags" 2)
(setq ob nil)
(PRINC)

(Command "-overkill" "All" "" "");REMOVES/COMBINES ANY DOUBLE LINES/CURVES/ETC
(PRINC)

(Command "-purge" "all" "" "no")
(PRINC)

(foreach x (mapcar 'cadr (ssnamex (ssget "X" '((0 . "ELLIPSE"))))); convert ELLIPSES to polylines
 (ACET-GEOM-ELLIPSE-TO-PLINE x)
 (entdel x)
)

(if (setq ss2 (ssget "_X" '((0 . "SPLINE")))); selects only SPLINES
  (command "_.splinedit" ss2 "p" "99"); then
);if

(setq ss2 nil); clear variable

(if (setq ss1 (ssget "_X" '((0 . "ELLIPSE,LWPOLYLINE,POLYLINE,ARC,LINE")))) ;; CIRCLE & SPLINE removed
  (command "_.pedit" "_m" ss1 "" "_J" "0.001" ""); then
); if

(setq ss1 nil); clear variable

(PRINC)
(command ".regen")
(PRINC)

(prompt "                                                                                                      OPERATION COMPLETE: SAVE FILE NOW")

(reset);reset variables-global error trap

(PRINC)
);defun

 

Thanks again Kent!

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

Post to forums  

Autodesk Design & Make Report

”Boost