Getting code to go threw a selection sett. LISP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi.
First of all. I'm having alot of fun learning LISP.
Some hair pulling. But man the dopamine boost when it start working.
I love this forum and all the help that is saved here over the years.
My background is not a programmer. Im self learned and LISP is my first really try sense i tried learning HTML early 2000'ds
So what im trying to do now is trying to get over a hurdle i cant seem to understand.
What am i trying to do?
Im trying to write a code that does a few things.
1. Selects all 3D solids in model space.
2. Make a block out of every 3D solid.
3. Name for the block comes from a polyline that have alot of xData in, that is linked to the 3D solid.
The model can have long over 1000+++ 3Dsolids inside. I don't have to have the code to do them all at one time as i know there are limitations. It's okey to have it being run a few times.
4. Then the plan is to add attributes with the tag and value from xdata to these blocks.
5. Get these attribute data to Autodesk Vault.
6. The blocks gets exported so inventor can read the model and start working there instead of AutoCad where parts have the ID name they have gotten from AutoCad (the company i work for have made there own hard customized AutoCad.)
7. As the parts name get over to inventor and the info to vault. link this together.
8. Be able to post the info required from vault to the company project management system (SQL)
Goal. Get the campany to the future of working with an 3D program instead of 3D in AutoCad and all the manual work that implies.
What i have done.
I have made a code some codes, thanks to a combination of help from this forum (google search), chatGPT, AutoCad help site, other cad help sites and general reading\tutorials on YouTube.
Block part.
That code i have for now can take a 3D solid manually. Make it to a block and manually choose the polyline that contains xdata.
That saves the block with the name from the xdata from the line.
So im trying to get this prosses to be automatic.
I have found there is a link between owener (polyline) and solid.
But i find it kind of sporadic to get to work.
I have been using "entnext" to get that polyline. Maby something else?
I have tried to find out as well how to get the code to circulate.
So that if it finds 3 solids. It does its job on one solid. And over to next. As it gets converted to a block. It should choose a new one. But i cant seem to even get it to select a 3Dsolid and make it to a block. I don't need it to be a specific solid as i want to open a drawing with many and just run it. so it can pick in a completely random fashion for all i care.
If need bee i can do it manually on any specific solid.
Attribute side.
I made a code that reads up to 8 tags and add these to the block.
I cant seem to make it to add more then 8 at a time. So i have split it up in 3 prosseses where the user gets asked what option they want to add to the block (the workaround for now)
I want it to be all Xdata containing on that line. As some have more then others.
I just cant seem to get it to either add more then 8 with predetermined "tags" or read all and post that.
Can be a total of 50 data points. the test objects i use for now have around 19-20.
What am i realy asking for?
Im asking for pointers. Some suggestions and on what to do. i will post the codes i have made for now just modified to not have company info in.
manually make a block:
(defun c:3DBLOCK (/ *error* errmsg :getblockanonymname s p n newname suffix count obj)
(defun *error* (errmsg)
;(setq *error* 'xx:Error)
(if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break,end"))
(princ (strcat "\nError: " errmsg)))
(setvar 'cmdecho 1)
(princ))
(defun :getblockanonymname ( / d r n)
(while (setq d (tblnext "BLOCK" (null d)))
(if (wcmatch (setq n (cdr (assoc 2 d))) "C$*")
(setq r (cons n r))))
(cond ((car (vl-sort r '>)))
("C$1000")))
(if (and (setq s (ssget))
(setq p '(0 0 0))
(setq n (cdr (assoc "XDATATAG" (get_xd_list (car (entsel))))))
(setvar 'cmdecho 0)
)
(progn
(setq newname n)
(setq suffix "")
(setq count 0)
(while (tblsearch "BLOCK" newname)
(setq count (1+ count))
(setq suffix (strcat "_" (itoa count)))
(setq newname (strcat n suffix)))
(command "_.-BLOCK" newname "_non" p s ""
"_.-INSERT" newname "_s" 1 "_r" 0 "_non" p)
(princ (strcat "\nBlock created '" newname " '"))
)
)
(*error* "end")
);End Defun
I found this code and modified it.
The original is here:
https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/a-lisp-routine-to-create-a-block-fro...
The attribute code:
(defun c:addattrPL1 (/ ss i blk blks def ent fu opt xdata-line posno jobno article mat mipsfas des stat thk prod nest fu bumto densi mipsar mipspa platea plateleng wbs )
(and
(setq ss (ssget '((0 . "INSERT"))))
(setq i (sslength ss))
(while (> i 0)
(setq blk (cdr (assoc 2 (entget (ssname ss (setq i (1- i)))))))
(if (not (vl-position blk blks))(setq blks (cons blk blks)))
)
)
(foreach blk blks
;get the xdata line
(vl-load-com)
(setq def (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) blk))
(setq ent (vlax-ename->vla-object (ssname ss 0)))
(setq xdata-line (car (entsel "\nSelect line containing XData: ")))
;tag definitions
(cond
(setq obj (cdr (assoc "XdataTAG1" (get_xd_list xdata-line))))
(setq posno (cdr (assoc "XdataTAG2" (get_xd_list xdata-line))))
(setq jobno (cdr (assoc "XdataTAG3" (get_xd_list xdata-line))))
(setq article (cdr(assoc "XdataTAG4" (get_xd_list xdata-line))))
(setq mat (cdr (assoc "XdataTAG5" (get_xd_list xdata-line))))
(setq mipsfas (cdr(assoc "XdataTAG6" (get_xd_list xdata-line))))
(setq des (cdr(assoc "XdataTAG7" (get_xd_list xdata-line))))
(setq stat (cdr(assoc "XdataTAG8" (get_xd_list xdata-line))))
(vla-addattribute def
2.5
acAttributeModeInvisible
"XdataTAG1"
(vlax-3D-point 0 0)
"XdataTAG1"
obj ; use the value of XdataTAG1 as the attribute value
)
(vla-addattribute def
2.5
acAttributeModeInvisible
"XdataTAG2"
(vlax-3D-point 0 0)
"XdataTAG2"
posno ; use the value of XdataTAG2 as the attribute value
)
(vla-addattribute def
2.5
acAttributeModeInvisible
"XdataTAG3"
(vlax-3D-point 0 0)
"XdataTAG3"
jobno ; use the value of XdataTAG3 as the attribute value
)
(vla-addattribute def
2.5
acAttributeModeInvisible
"XdataTAG4"
(vlax-3D-point 0 0)
"XdataTAG4"
article ; use the value of XdataTAG4 as the attribute value
)
(vla-addattribute def
2.5
acAttributeModeInvisible
"XdataTAG5"
(vlax-3D-point 0 0)
"XdataTAG5"
mat ; use the value of XdataTAG5 as the attribute value
)
(vla-addattribute def
2.5
acAttributeModeInvisible
"XdataTAG6"
(vlax-3D-point 0 0)
"XdataTAG6"
mipsfas ; use the value of XdataTAG6 as the attribute value
)
(vla-addattribute def
2.5
acAttributeModeInvisible
"XdataTAG7"
(vlax-3D-point 0 0)
"XdataTAG7"
des ; use the value of XdataTAG7 as the attribute value
)
(vla-addattribute def
2.5
acAttributeModeInvisible
"XdataTAG8"
(vlax-3D-point 0 0)
"XdataTAG8"
stat ; use the value of XdataTAG8 as the attribute value
)
(t (princ "\nInvalid option selected."))
);end cond
(command "_.attsync" "_N" blk)
);End foreach
(princ)
(vl-load-com)
);End Defun
This is built up from this forum, chatgpt, me reading and fixing and working and well using a week with tweaking and testing. hehehe.
the code i have used to test the choose polyline automatically for a 3Dsolid.
this just post the handle number for them. But i can get this to work. But i cant modify it for the life of me to do anything else really.
(defun c:getpoly ()
;get solid
(setq ss (ssget "x"'((0 . "3DSOLID"))))
(if ss (progn(setq ssl (sslength ss))(setvar "CMDECHO" 1)))
(while (> ssl 1)
(setq edata (entget (setq e (ssname ss (setq ssl (1- ssl))))))
(setq edata name)
;get polyline
(setq pline (entnext name))
;print handle for solid and polyline
(princ (strcat "\nP-line handle: " (strcase (cdr (assoc 5 (entget pline))))))
(princ (strcat "\nSolid handle: " (strcase (cdr (assoc 5 (entget name))))))
);end while
);end
And this is modified from this code that does this manually (chatGPT):
(defun c:plinehandle ()
(setq solid (car (entsel "\nSelect the 3D solid: ")))
(setq pline (entnext solid))
(princ (strcat "\nSolid handle: " (strcase (cdr (assoc 5 (entget solid))))))
(princ (strcat "\nP-line handle: " (strcase (cdr (assoc 5 (entget pline)))))))
Thank you for your attention.
And thank you for your help on beforehand.