C. Roberts Posted August 27 Posted August 27 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? Quote
CyberAngel Posted August 27 Posted August 27 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. Quote
Tsuky Posted August 27 Posted August 27 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 Quote
C. Roberts Posted August 27 Author Posted August 27 @Tsuky I don't want to have any user input other than them having to start the lisp by typing in the command. Quote
C. Roberts Posted August 28 Author Posted August 28 @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)) Quote
Tsuky Posted August 28 Posted August 28 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) )) Quote
C. Roberts Posted August 28 Author Posted August 28 @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 Quote
Tsuky Posted August 28 Posted August 28 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) ) Quote
C. Roberts Posted August 28 Author Posted August 28 @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") ) Quote
Tsuky Posted August 28 Posted August 28 (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 August 28 by Tsuky 1 Quote
BIGAL Posted August 29 Posted August 29 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. 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.