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!
Solved! Go to Solution.
Solved by Kent1Cooper. Go to Solution.
Solved by dbroad. Go to Solution.
ssdel needs to be passed an entity name (to be removed) and a selection set (to remove it from).
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.
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
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 )) )
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)
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
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
....
@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
....
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.
@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
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!
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!!
@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".
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
@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.
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)??
@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
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!