Jump to content

Get height property of a text object inside of a block with exploding block


Recommended Posts

Posted

I use a text object within a block to set my scaling factor for other objects I am having the lisp insert.

Currently the lisp looks for a certain block name and explodes it then looks for the text object "REVISIONS" and stores the height of the text object in the symbol "txtht".

 

(cond
    ;; --- Find and explode block named "FSTITLE" and get height of the text object "REVISIONS" --- ;;
    ((tblsearch "BLOCK" "FSTITLE")
     (command "EXPLODE" (ssget "X" '((0 . "INSERT") (2 . "FSTITLE"))))
     (setq txtht (cdr (assoc 40 (entget (ssname (ssget "X" '((0 . "TEXT") (1 . "REVISIONS"))) 0))))))

    ;; --- Find and explode block named "VTITLE" and get height of the text object "REVISIONS" --- ;;
    ((tblsearch "BLOCK" "VTITLE")
     (command "EXPLODE" (ssget "X" '((0 . "INSERT") (2 . "VTITLE"))))
     (setq txtht (cdr (assoc 40 (entget (ssname (ssget "X" '((0 . "TEXT") (1 . "REVISIONS"))) 0))))))

    ;; --- Find a block named "BEHLEN_CVR" and get height of the text object "REVISIONS"
    ((tblsearch "BLOCK" "BEHLEN_CVR")
     (setq txtht (cdr (assoc 40 (entget (ssname (ssget "X" '((0 . "TEXT") (1 . "REVISIONS"))) 0))))))

    ;; --- Find and explode block named "LOGO" and get height of the text object "REVISIONS" --- ;;
    ((tblsearch "BLOCK" "LOGO")
     (command "EXPLODE" (ssget "X" '((0 . "INSERT") (2 . "LOGO"))))
     (setq txtht (cdr (assoc 40 (entget (ssname (ssget "X" '((0 . "TEXT") (1 . "REVISIONS"))) 0))))))
  )

 

Is there a way to get into the block without exploding it and extract the height of the text object?

Posted

Take a look at this page for how to get into the block definition and pull out the text object.

 

Then look at this page for the text object codes. Height is 40.

 

We try to let members work out solutions on their own so that they learn to program, instead of doing the work for them. If you need help, though, let us know.

Posted

It seems to me that the lisp function (nentsel) corresponds to your needs, because it returns the entity directly even if it is nested in a block

Posted

@Tsuky I don't want to have any user input other than them having to start the lisp by typing in the command.

Posted

@CyberAngel is a text object that is not an attribute an object that is able to be found with entnext?

 

If I store the entity of the block named FSTITLE and use entnext it goes to another block it doesn't go inside the FSTITLE block.

 

Command: (setq blkss (ssget "X" '((0 . "INSERT") (2 . "FSTITLE"))))
<Selection set: f>
Command: (setq blkent (ssname blkss 0))
<Entity name: 24307e82ba0>
Command: (setq blkentp (entget blkent))
((-1 . <Entity name: 24307e82ba0>) (0 . "INSERT") (330 . <Entity name: 202381b5ef0>) (5 . "1192") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbBlockReference") (2 . "FSTITLE") (10 0.0 0.0 0.0) (41 . 133.013) (42 . 133.013) (43 . 133.013) (50 . 0.0) (70 . 0) (71 . 0) (44 . 0.0) (45 . 0.0) (210 0.0 0.0 1.0))
Command: (setq blkentnext (entnext blkent))
<Entity name: 24307e82bb0>
Command: (setq blkentnextp (entget blkentnext))
((-1 . <Entity name: 202381b5bb0>) (0 . "INSERT") (330 . <Entity name: 24307e82ef0>) (5 . "1193") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbBlockReference") (2 . "FSSUB30") (10 113.061 232.773 0.0) (41 . 133.013) (42 . 133.013) (43 . 133.013) (50 . 0.0) (70 . 0) (71 . 0) (44 . 0.0) (45 . 0.0) (210 0.0 0.0 1.0))

 

Posted

 

Without being able to test without your blocks

((lambda ( / ent txtht)
  (mapcar
    '(lambda (x)
      (setq ent (cdar (entget (tblobjname "BLOCK" x))))
      (while ent
        (if (eq (cdr (assoc 0 (entget ent))) "TEXT")
          (setq txtht (cons (cdr (assoc 40 (entget ent))) txtht)) 
        )
        (setq ent (entnext (cdar (entget ent))))
      )
    )
    '("FSTITLE" "VTITLE" "BEHLEN_CVR" "LOGO")
  )
  (print txtht)
  (prin1)
))

 

Posted

@Tsuky I put your portion of code in a defun, loaded it, and ran it.

I got "error: bad argument type: lentityp nil" after running the lisp.

 

(defun c:testing ()
((lambda ( / ent txtht)
  (mapcar
    '(lambda (x)
      (setq ent (cdar (entget (tblobjname "BLOCK" x))))
      (while ent
        (if (eq (cdr (assoc 0 (entget ent))) "TEXT")
          (setq txtht (cons (cdr (assoc 40 (entget ent))) txtht)) 
        )
        (setq ent (entnext (cdar (entget ent))))
      )
    )
    '("FSTITLE" "VTITLE" "BEHLEN_CVR" "LOGO")
  )
  (print txtht)
  (prin1)
))
)

 

I attached a drawing that has the FSTITLE block in it.  AnDwg-5.dwg

Posted

I had assumed that all the blocks existed in the drawing. I added a condition.

(defun c:testing ( / txtht)
  (mapcar
    '(lambda (x / tbl ent)
      (cond
        ((setq tbl (tblobjname "BLOCK" x))
          (setq ent (entget tbl))
          (while (setq ent (entnext (cdar ent)))
            (setq ent (entget ent))
            (print (cdr (assoc 0 ent)))
            (if (eq (cdr (assoc 0 ent)) "TEXT")
              (setq txtht (cons (cdr (assoc 40 ent)) txtht))
            )
          )
        )
      )
    )
    '("FSTITLE" "VTITLE" "BEHLEN_CVR" "LOGO")
  )
  (print txtht)
  (prin1)
)

 

Posted

@Tsuky now I have a couple problems.

 

The program that generates the drawing scales the blocks.  We have a template block that get scaled differently on every drawing.  The base block has a text height of .08" for the REVISION text and even though the block is scaled up and the text height is larger now if I recall whats inside the symbol txtht it shows (.08 .08).

Command: !txtht
(0.08 0.08)

Is there a way to update the block information before trying to extract the height of the text?  If not, I will just keep my old code and have the block explode first then find the text object.

 

With that the other problem is that the symbol txtht is storing 2 values in it because there are 2 text entities that have REVISIONS as its contents.  How do I get the while loop to stop after it finds the 1st text object that has "REVISIONS" as its contents?  Or, would it be better to just use a 'car' in the (setq txtht... line?

 

It is creating a list with 2 values in it and it is screwing up the rest of the lisp where I use txtht.

 

The code below is what I am using in my lisp currently

I added an 'and' to the if statement so that it would only get text objects with "REVISIONS" as its contents.

 

  (mapcar
    '(lambda (x / tbl ent)
      (cond
        ((setq tbl (tblobjname "BLOCK" x))
          (setq ent (entget tbl))
          (while (setq ent (entnext (cdar ent)))
            (setq ent (entget ent))
            (if (and (eq (cdr (assoc 0 ent)) "TEXT")
                     (eq (cdr (assoc 1 ent)) "REVISIONS"))
              (setq txtht (cons (cdr (assoc 40 ent)) txtht))
            )
          )
        )
      )
    )
  '("FSTITLE" "VTITLE" "LOGO")
  )

 

 

Posted (edited)

You are right, I only queried the block definition.
If the block is inserted at least once, the first insertion will be queried and the height will be multiplied by the scale factor in Y else the value 0.0 is returned.
Will this fit?

(defun c:testing ( / txtht)
  (mapcar
    '(lambda (x / tbl ent ss scal_y)
      (cond
        ((setq tbl (tblobjname "BLOCK" x))
          (setq ent (entget tbl))
          (while (setq ent (entnext (cdar ent)))
            (setq ent (entget ent))
            (if (and (eq (cdr (assoc 0 ent)) "TEXT") (eq (cdr (assoc 1 ent)) "REVISIONS"))
              (setq txtht (cdr (assoc 40 ent)))
            )
          )
          (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 x))))
          (cond
            (ss
              (setq
                scal_y (cdr (assoc 42 (entget (ssname ss 0))))
                txtht (* txtht scal_y)
              )
            )
            (T (setq txtht 0.0))
          )
        )
      )
    )
    '("FSTITLE" "VTITLE" "BEHLEN_CVR" "LOGO")
  )
  (print txtht)
  (prin1)
)

 

Edited by Tsuky
  • Thanks 1
Posted

Just a question are you using layouts and the block is your layout Title block, sounds like it, or are you using multiple title blocks in "Model space" ? I ask as using layouts gets rid of all these problems.

Posted

Thank you everyone for the help!!

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