Bulina Posted February 16 Posted February 16 Hello, Did not know exactly what to look for in the previous posts as not sure how to name the blocks I had. So, I do have a dxf file with objects exported from a different software, these objects seem to be recognized by Civil as blocks with attributes, and each object is assigned to a different block name. When trying to edit them couldn't find any attributes. The problem here is there might be thousands like this in the file, and I do need to label them using 2 of their attributed fields to avoid doing this manually. I have tried different options of labelling available in civil 3d but got no results as don't know exactly what type of object they are. There might be an option to be able to extract the information from those objects. If somebody has an idea it will be much appreciated. I have attached an example of how the properties field looks like when objects are selected. 1.dwg Quote
BIGAL Posted February 17 Posted February 17 (edited) Ok you can get the blocks into a selection set using a wild card search as 1st step, can then get attributes. Then you can check for an attribute tagname. (setq ss (ssget "X" '((0 . "INSERT")(cons 2 "Abschn_11_3_NN009*")))) <Selection set: 0000000064361620> : (sslength ss) 115 (vlax-get (nth 3 atts) 'Tagstring) "DN" (vlax-get (nth 3 atts) 'Textstring) "200.00" What do you know about lisp ? Edited February 17 by BIGAL 1 Quote
Bulina Posted February 19 Author Posted February 19 On 2/17/2024 at 10:27 PM, BIGAL said: Ok you can get the blocks into a selection set using a wild card search as 1st step, can then get attributes. Then you can check for an attribute tagname. (setq ss (ssget "X" '((0 . "INSERT")(cons 2 "Abschn_11_3_NN009*")))) <Selection set: 0000000064361620> : (sslength ss) 115 (vlax-get (nth 3 atts) 'Tagstring) "DN" (vlax-get (nth 3 atts) 'Textstring) "200.00" What do you know about lisp ? Hi Bigal, Many thanks for taking the time to find an answer to my problem. Don't know much about lisps, maybe to read them but can't write them. Is your suggestion working when there are thousands of blocks, each one having a unique name? Attributes are the same for all of them, just the values are different. Quote
CyberAngel Posted February 19 Posted February 19 It looks like the block name was built using the STRNR, AP, and EP values (not sure where the 2 came from). There's a clue to the type of object in the name: Ab is a prefix for almost all proxy objects, so schn may tell you what kind of object it should be. As BigAl suggests, you may be able to read the attribute data and create... uh, whatever you need to create using that data. Recently I learned how to create new entities with AutoLISP (instead of modifying old ones), and if I can do it, anyone can. You have to know what DXF codes to use and what values to assign to them, but the rest is relatively easy. Quote
BIGAL Posted February 20 Posted February 20 Ok need "using 2 of their attributed fields to avoid doing this manually" what are the tag names ? Post a dwg showing at least one example block and text required, note set the text to the style required, layer and text height. Quote
Bulina Posted February 20 Author Posted February 20 18 hours ago, BIGAL said: Ok need "using 2 of their attributed fields to avoid doing this manually" what are the tag names ? Post a dwg showing at least one example block and text required, note set the text to the style required, layer and text height. There is a dwg file attached to my first post with 4 proxy blocks. I will attach it again. I need to label the LXY and TAUPUR. Text size and style are not important, could be anything, as well the layer is not important. What I am looking for is just some of the information from inside the block, to avoid making the notes manually for now. Everything else is just extra detail. Thank you 1.dwg Quote
BIGAL Posted February 21 Posted February 21 Ok the blocks have some serious issues making just auto labeling very hard, each block is individual and the line work for each is no where near the insert point. So if you just want to see try this, I set textsize to 150. This is very rough. ; LXY and TAUPUR. (defun wow ( / ) (while (setq ent (entsel "\npick a block Enter to exit ")) (setq obj (vlax-ename->vla-object (car ent))) (setq atts (vlax-invoke obj 'Getattributes)) (foreach att atts (if (= (vlax-get att 'Tagstring) "LXY") (setq str1 (vlax-get att 'Textstring) ) ) (if (= (vlax-get att 'Tagstring) "TAUPUR") (princ (setq str2 (vlax-get att 'Textstring))) ) ) (setq str (strcat str1 "\n" str2)) (setq pt (cdr ent)) (command "-mtext" pt pt str "") ) (princ) ) (wow) 1 Quote
Bulina Posted February 21 Author Posted February 21 (edited) Yeap, it seems the export to CAD from that software is something that is not quite CAD friendly. The code above, asks me for the block selection, and after selecting one just pops in the appload window again. Got the below error: Command: pick a block Enter to exit Can't reenter LISP. *Invalid selection* Expects a point or Last pick a block Enter to exit *Cancel* ; error: Function cancelled Did try the chatGBT last night and got this code, had to work around with the chat to get something but still after solving the errors and loading the lisp, it doesn't recognize the function as an unknown command. (defun extract-attributes (proxyObj / attribs) (setq attribs (entget proxyObj)) (foreach att attribs (if (= (car att) -1) ; Attribute marker (progn (setq att (cdr att)) (if (= (cdr (assoc 0 att)) "TEXT") ; Check for TEXT entity (progn (setq att (cdr att)) ; Get attribute list (while att (if (member (cdr (assoc 2 att)) '("LXY" "TAUPUR")) ; Check for specific attributes (progn (setq tag (cdr (assoc 2 att))) (setq att (cdr att)) ; Move to attribute value (setq value (cdr att)) (setq att nil) ; Exit the loop (princ (strcat "Tag: " tag ", Value: " value "\n")) ) ) (setq att (cdr att)) ; Move to next attribute ) ) ) ) ) ) ) (defun wonder () (setq space (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object)))) (setq proxyObjs '()) (vla-StartUndoMark (vla-get-ActiveDocument (vlax-get-acad-object))) (vlax-for obj space (if (= (vla-get-ObjectName obj) "AcDbProxyObject") ; Check if object is a proxy (setq proxyObjs (cons obj proxyObjs)) ) ) (foreach obj proxyObjs (extract-attributes (vla-get-ObjectID obj)) ) (vla-EndUndoMark (vla-get-ActiveDocument (vlax-get-acad-object))) ) (wonder) Edited February 21 by SLW210 Added Code Tags! Quote
SLW210 Posted February 21 Posted February 21 Please use Code Tags in the future when posting code. (use the <> in the editor toolbar) 1 Quote
Bulina Posted February 21 Author Posted February 21 32 minutes ago, SLW210 said: Please use Code Tags in the future when posting code. (use the <> in the editor toolbar) I am sorry, was not aware, as obvious I did not read the rules. Thank you for the correction. I will be aware next time Quote
SLW210 Posted February 21 Posted February 21 No worries, that's why we explain it and provide information. Quote
BIGAL Posted February 22 Posted February 22 (edited) Not sure what to say, tested again against 1.dwg, I did though do "Textsize" 150 1st. If you want to repeat change wow to c:wow or a name you want to use but add the C :. Are you sure it did not work but text maybe tiny. Edited February 22 by BIGAL 1 Quote
Bulina Posted February 22 Author Posted February 22 Now I am confused myself as well. Is either I am doing something wrong or my Cad is missing something. It looks is listing something but for sure there is no text in the model space. Looks like the results of the listing are considered commands. Still got the error of function not recognized. After calling the function from the command bar it asks me to select the blocks but got the unknown command as a result. If I expand the command prompt I got this. It might be something I am doing wrong. ; LXY and TAUPUR. (defun c:foam ( / ) (while (setq ent (entsel "\npick a block Enter to exit ")) (setq obj (vlax-ename->vla-object (car ent))) (setq atts (vlax-invoke obj 'Getattributes)) (foreach att atts (if (= (vlax-get att 'Tagstring) "LXY") (setq str1 (vlax-get att 'Textstring) ) ) (if (= (vlax-get att 'Tagstring) "TAUPUR") (princ (setq str2 (vlax-get att 'Textstring))) ) ) (setq str (strcat str1 "\n" str2)) (setq pt (cdr ent)) (command "-mtext" pt pt str "") ) (princ) ) (foam) Quote
BIGAL Posted February 23 Posted February 23 (c:foam) this implies run the function on loading, if you want to run again just type FOAM on the command line. I just write a lot of my code once it is loaded, run it, knowing may need to run again, so no need to load each time 1 Quote
Bulina Posted February 26 Author Posted February 26 On 2/23/2024 at 11:48 PM, BIGAL said: (c:foam) this implies run the function on loading, if you want to run again just type FOAM on the command line. I just write a lot of my code once it is loaded, run it, knowing may need to run again, so no need to load each time Hi Bigal, Many thanks for explaining. It does make sense what you're saying above. But, on mine, first thing after ''apploading'' the .lsp file I am being asked to pick a block, next step is me selecting one and the result is the ''appload'' window asking for file selection again. Quote
Bulina Posted February 26 Author Posted February 26 It seems my Cad did not get right the 'command' line. Got it fixed with this below. Managed to get the text and the values but now I've got a problem with the position of the text, all are going to the insertion point, which in my case, all blocks have the same insertion point, giving me all the texts overlapping. (defun c:foam2 (/) (while (setq ent (entsel "\npick a block Enter to exit ")) (setq obj (vlax-ename->vla-object (car ent))) (setq atts (vlax-invoke obj 'Getattributes)) (setq str1 nil str2 nil) (foreach att atts (if (= (vlax-get att 'Tagstring) "LXY") (setq str1 (vlax-get att 'Textstring))) (if (= (vlax-get att 'Tagstring) "TAUPUR") (setq str2 (vlax-get att 'Textstring)))) (setq str (strcat str1 "\n" str2)) (setq blockPt (cdr (assoc 10 (entget (car ent))))) ; Get the insertion point of the block (setq textPt (mapcar '+ blockPt '(5.0 0.0 0.0))) ; Calculate the position next to the block (create-mtext textPt str) ) (princ) ) (defun create-mtext (pt str) (setq mtext (vla-addMText (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object))) (vlax-3d-point pt) ; Convert point to 3D point 0.0 str)) (vla-put-Height mtext 100.0) ; Set the height of MTEXT (vla-put-Width mtext 500.0) ; Set the width of MTEXT mtext ) Quote
CyberAngel Posted February 26 Posted February 26 A strategy that helps me debug is including trace statements. When you're not sure what a variable's value is, or even if you think you know, include a princ statement to print it out. Example: I have a real number variable named rando, so here's the trace statement: (princ (strcat "rando=" (rtos rando)) ":") I include the colon in case there's another trace statement after this one. You can always comment out these statements. In your case, you may want to print the values of blockPt and textPt to see what's happening. 1 Quote
Recommended Posts
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.