Jump to content

Recommended Posts

Posted

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.image.thumb.png.d7aa6d114e6635451cf796080f215ee8.png

1.dwg

Posted (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 by BIGAL
  • Thanks 1
Posted
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.

Posted

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.

Posted

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.

Posted
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

Posted

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)

 

 

  • Thanks 1
Posted (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 by SLW210
Added Code Tags!
Posted

Please use Code Tags in the future when posting code. (use the <> in the editor toolbar)

  • Thanks 1
Posted
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

Posted

No worries, that's why we explain it and provide information.

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

 

image.png.fd566f4769ff3dfe2b4445f2b98782f7.png

Edited by BIGAL
  • Thanks 1
Posted

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.

image.png.063e8b8f337119af812251d5f1a3fbc6.png

 

 

; 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)

 

Posted

(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

  • Thanks 1
Posted
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. 

Posted

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
)

 

Posted

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.

  • Like 1

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