Author Topic: Attributed text fit in bounding box  (Read 4317 times)

0 Members and 1 Guest are viewing this topic.

jlogan02

  • Bull Frog
  • Posts: 327
Attributed text fit in bounding box
« on: March 13, 2018, 03:19:11 PM »
We use an EDM software that lets us tie the Properties card in the software to an attribute in the drawing. The administrator develops an excel file of all of our location names then links that name to a field in the properties card that's then linked to the attribute in the drawing. The problem is, some of the location names have more text and spaces in them than the title block will accomodate.

Simple solution, use Fit justification. Simply horrible results as far as I'm concerned.

I need to...
get the width of the title block and create a bounding box
if text is outside bounding box or width of title block, make it fit inside
if text is inside bounding box or width of title block, leave it alone.

Is this possible within an attribute. I could see it being done with text or mtext. Just have no clue about attributes.

J Logan
ACAD2015


« Last Edit: March 13, 2018, 03:25:10 PM by jlogan02 »
J. Logan
ACAD 2018

I am one with the Force and the Force is with me.
AutoCAD Map 2018 Windows 10

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Attributed text fit in bounding box
« Reply #1 on: March 13, 2018, 03:34:22 PM »
The attribute has a scalefactor property. Is this what you're looking for?

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

jlogan02

  • Bull Frog
  • Posts: 327
Re: Attributed text fit in bounding box
« Reply #2 on: March 13, 2018, 03:53:41 PM »
Thanks for the provided link to object.scalefactor.

Correct me if I'm wrong, but is it talking about the scale factor for the entire attribute? Which would cover every line in an attribute. All lines of text in the images I provided are part of the attribute with exception to the REFERENCE DRAWING text at top. So they would all be exposed to the object.scalefactor. Correct?

J. Logan
ACAD 2015
J. Logan
ACAD 2018

I am one with the Force and the Force is with me.
AutoCAD Map 2018 Windows 10

ronjonp

  • Needs a day job
  • Posts: 7531
Re: Attributed text fit in bounding box
« Reply #3 on: March 13, 2018, 04:09:54 PM »
Thanks for the provided link to object.scalefactor.

Correct me if I'm wrong, but is it talking about the scale factor for the entire attribute? Which would cover every line in an attribute. All lines of text in the images I provided are part of the attribute with exception to the REFERENCE DRAWING text at top. So they would all be exposed to the object.scalefactor. Correct?

J. Logan
ACAD 2015
Try it :)
Code - Auto/Visual Lisp: [Select]
  1. (defun c:foo (/ s)
  2.   (if (setq s (ssget ":L" '((0 . "insert") (66 . 1))))
  3.     (foreach b (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
  4.       (foreach a (vlax-invoke (vlax-ename->vla-object b) 'getattributes)
  5.         (vla-put-scalefactor a 0.5)
  6.       )
  7.     )
  8.   )
  9.   (princ)
  10. )

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Attributed text fit in bounding box
« Reply #4 on: March 13, 2018, 04:29:24 PM »
Bare bones ...

Code: [Select]
(defun mpx-get-bounding-box ( object / a b )
    (vl-catch-all-apply 'vlax-invoke-method (list object 'GetBoundingBox 'a 'b))
    (if a (mapcar 'vlax-safearray->list (list a b)))
)

(defun mpx-restrict-attrib-width ( block-reference max-width / bb dx ratio flag )
    (and
        (eq 'vla-object (type block-reference))
        (eq "AcDbBlockReference" (vla-get-objectname block-reference))
        (eq :vlax-true (vla-get-hasattributes block-reference))
        (foreach a (vlax-invoke block-reference 'GetAttributes)
            (and
                (setq bb (mpx-get-bounding-box a))
                (setq dx (abs (apply '- (mapcar 'car bb))))
                (< 1.0 (setq ratio (/ dx max-width)))
                (setq flag t)
                (vla-put-scalefactor a (* (vla-get-scalefactor a) (/ 1.0 ratio)))
            )       
        )
        (if flag (vla-update block-reference))
    )
    (princ)
)

(defun c:foo ( / ename block-reference max-width )
    (and
        (vl-load-com)
        (setq ename (car (entsel "\nSelect an attributed block: ")))
        (setq block-reference (vlax-ename->vla-object ename))
        (eq "AcDbBlockReference" (vla-get-objectname block-reference))
        (eq :vlax-true (vla-get-hasattributes block-reference))
        (progn
            (initget (logior 1 2 4))
            (setq max-width (getdist "\nEnter the maximum attribute width: "))
        )   
        (mpx-restrict-attrib-width block-reference max-width)
    )
    (princ)   
)
« Last Edit: March 13, 2018, 04:32:48 PM by MP »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Lee Mac

  • Seagull
  • Posts: 12922
  • London, England
Re: Attributed text fit in bounding box
« Reply #5 on: March 13, 2018, 06:39:01 PM »
Correct me if I'm wrong, but is it talking about the scale factor for the entire attribute? Which would cover every line in an attribute. All lines of text in the images I provided are part of the attribute with exception to the REFERENCE DRAWING text at top. So they would all be exposed to the object.scalefactor. Correct?

Are you using Multiline Attributes?

jlogan02

  • Bull Frog
  • Posts: 327
Re: Attributed text fit in bounding box
« Reply #6 on: March 14, 2018, 10:12:29 AM »
Correct me if I'm wrong, but is it talking about the scale factor for the entire attribute? Which would cover every line in an attribute. All lines of text in the images I provided are part of the attribute with exception to the REFERENCE DRAWING text at top. So they would all be exposed to the object.scalefactor. Correct?

Are you using Multiline Attributes?

If you mean using the multi-line option of attdef, No.

There are 17 lines in the attribute without the "Multiple Line" option checked.

ATT
Text height = .25
Text width = .85
Title block will hold 22 W's. I tried to verify how many of the biggest letter it would accommodate at that width.
1st 4 lines have the same text properties although TitleLine1 typically has the most variation.


J. Logan
ACAD 2015
J. Logan
ACAD 2018

I am one with the Force and the Force is with me.
AutoCAD Map 2018 Windows 10

jlogan02

  • Bull Frog
  • Posts: 327
Re: Attributed text fit in bounding box
« Reply #7 on: March 14, 2018, 10:36:16 AM »
Bare bones ...

Code: [Select]
(defun mpx-get-bounding-box ( object / a b )
    (vl-catch-all-apply 'vlax-invoke-method (list object 'GetBoundingBox 'a 'b))
    (if a (mapcar 'vlax-safearray->list (list a b)))
)

(defun mpx-restrict-attrib-width ( block-reference max-width / bb dx ratio flag )
    (and
        (eq 'vla-object (type block-reference))
        (eq "AcDbBlockReference" (vla-get-objectname block-reference))
        (eq :vlax-true (vla-get-hasattributes block-reference))
        (foreach a (vlax-invoke block-reference 'GetAttributes)
            (and
                (setq bb (mpx-get-bounding-box a))
                (setq dx (abs (apply '- (mapcar 'car bb))))
                (< 1.0 (setq ratio (/ dx max-width)))
                (setq flag t)
                (vla-put-scalefactor a (* (vla-get-scalefactor a) (/ 1.0 ratio)))
            )       
        )
        (if flag (vla-update block-reference))
    )
    (princ)
)

(defun c:foo ( / ename block-reference max-width )
    (and
        (vl-load-com)
        (setq ename (car (entsel "\nSelect an attributed block: ")));;select attribute
        (setq block-reference (vlax-ename->vla-object ename));;set block reference variable
        (eq "AcDbBlockReference" (vla-get-objectname block-reference));;get block reference name ???
        (eq :vlax-true (vla-get-hasattributes block-reference));;if block has attributes, do the following???
        (progn
            (initget (logior 1 2 4));;Not sure what this is doing. I'll do some reading.
            (setq max-width (getdist "\nEnter the maximum attribute width: "));;set the max width to user selected width
)   
        (mpx-restrict-attrib-width block-reference max-width);;keep attribute width inside block reference maximum width
    )
    (princ)   
)

This works nicely. Please, check my comments. I'm not sure I understand exactly what's happening.
 
It would be nice if this occurred without user input.
I'll try to explain the process a little bit better...
User fills out a card in the EDM software which is linked to the attribute in AutoCAD. TitleLine1 can be exceptionally long (we're working on shortening that on the EDM side right now)
User completes the card creation and closes the card.
User selects the drawing file to open from the EDM software
AutoCAD opens and the title block is filled out automagically via the CARD from the EDM.
TileLine1 has a set width of .85, if the CARD in the EDM has a TitleLine1 that's too big to fit, it overruns the titleblock.
User has to manually adjust the attribute to fit. Instead of manually here, maybe upon startup, check TitleLine1 if it's outside the title block width (bounding box? Maybe, I don't know)

It works fine the way it is and the boss was expecting a simple button push. So, I can give him what he wants with credit to MP.
« Last Edit: March 14, 2018, 10:43:48 AM by jlogan02 »
J. Logan
ACAD 2018

I am one with the Force and the Force is with me.
AutoCAD Map 2018 Windows 10

jlogan02

  • Bull Frog
  • Posts: 327
Re: Attributed text fit in bounding box
« Reply #8 on: March 14, 2018, 10:40:53 AM »
Thanks for the provided link to object.scalefactor.

Correct me if I'm wrong, but is it talking about the scale factor for the entire attribute? Which would cover every line in an attribute. All lines of text in the images I provided are part of the attribute with exception to the REFERENCE DRAWING text at top. So they would all be exposed to the object.scalefactor. Correct?

J. Logan
ACAD 2015
Try it :)
Code - Auto/Visual Lisp: [Select]
  1. (defun c:foo (/ s)
  2.   (if (setq s (ssget ":L" '((0 . "insert") (66 . 1))))
  3.     (foreach b (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
  4.       (foreach a (vlax-invoke (vlax-ename->vla-object b) 'getattributes)
  5.         (vla-put-scalefactor a 0.5)
  6.       )
  7.     )
  8.   )
  9.   (princ)
  10. )

I stand corrected. I tried the example code from the help file you linked to and it seemed to be scaling it up and down. Yours clearly works just fine. Well done sir.

J. Logan
ACAD 2015
J. Logan
ACAD 2018

I am one with the Force and the Force is with me.
AutoCAD Map 2018 Windows 10

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Attributed text fit in bounding box
« Reply #9 on: March 14, 2018, 11:32:07 AM »
Forgive me but I have like 2 minutes to work on extra curricular stuff so abbreviated posts are abbreviated.

Review this starter code:

Code: [Select]
(defun mpx-get-bounding-box ( object / a b )
    (vl-catch-all-apply 'vlax-invoke-method (list object 'GetBoundingBox 'a 'b))
    (if a (mapcar 'vlax-safearray->list (list a b)))
)

;;  note: name and arguments changed from original post

(defun mpx-restrict-attrib-widths ( block-reference tag-spec max-width / bb dx ratio flag )
    (and
        (eq 'vla-object (type block-reference))
        (eq "AcDbBlockReference" (vla-get-objectname block-reference))
        (eq :vlax-true (vla-get-hasattributes block-reference))
        (setq tag-spec (strcase (if (eq 'str (type tag-spec)) tag-spec "*")))
        (foreach a (vlax-invoke block-reference 'GetAttributes)
            (and
                (wcmatch (vla-get-tagstring a) tag-spec)
                (setq bb (mpx-get-bounding-box a))
                (setq dx (abs (apply '- (mapcar 'car bb))))
                (< 1.0 (setq ratio (/ dx max-width)))
                (setq flag t)
                (vla-put-scalefactor a (* (vla-get-scalefactor a) (/ 1.0 ratio)))
            )       
        )
        (if flag (vla-update block-reference))
    )
    (princ)
)

(defun c:Foo ( / block-spec tag-spec max-width ss i )

    (vl-load-com)

    ;;  please provide these values:

    (setq
        block-spec "OUR-TITLE-BLOCK-NAME"
        tag-spec   "TITLE*#*"
        max-width  10
    )

    (if (setq ss (ssget "x" (list '(0 . "insert")'(66 . 1)(cons 2 block-spec))))
        (repeat (setq i (sslength ss))
            (mpx-restrict-attrib-widths
                (vlax-ename->vla-object (ssname ss (setq i (1- i))))
                tag-spec
                max-width
            )
        )
    )
   
    (princ)
   
)

Cheers.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

jlogan02

  • Bull Frog
  • Posts: 327
Re: Attributed text fit in bounding box
« Reply #10 on: March 30, 2018, 12:38:25 PM »
Just getting back to this. Wow!! Both options work perfectly for what I'm attempting.

I'm going with MPs code as it fits our users methods better.

Thanks for the reply's and code.

J. Logan
ACAD2015
J. Logan
ACAD 2018

I am one with the Force and the Force is with me.
AutoCAD Map 2018 Windows 10

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Attributed text fit in bounding box
« Reply #11 on: March 31, 2018, 01:06:45 PM »
Glad to hear we could help; thanks for letting us know.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

jlogan02

  • Bull Frog
  • Posts: 327
Re: Attributed text fit in bounding box
« Reply #12 on: April 12, 2018, 01:43:23 PM »
Forgive me but I have like 2 minutes to work on extra curricular stuff so abbreviated posts are abbreviated.

Review this starter code:

Code: [Select]
(defun mpx-get-bounding-box ( object / a b )
    (vl-catch-all-apply 'vlax-invoke-method (list object 'GetBoundingBox 'a 'b))
    (if a (mapcar 'vlax-safearray->list (list a b)))
)

;;  note: name and arguments changed from original post

(defun mpx-restrict-attrib-widths ( block-reference tag-spec max-width / bb dx ratio flag )
    (and
        (eq 'vla-object (type block-reference))
        (eq "AcDbBlockReference" (vla-get-objectname block-reference))
        (eq :vlax-true (vla-get-hasattributes block-reference))
        (setq tag-spec (strcase (if (eq 'str (type tag-spec)) tag-spec "*")))
        (foreach a (vlax-invoke block-reference 'GetAttributes)
            (and
                (wcmatch (vla-get-tagstring a) tag-spec)
                (setq bb (mpx-get-bounding-box a))
                (setq dx (abs (apply '- (mapcar 'car bb))))
                (< 1.0 (setq ratio (/ dx max-width)))
                (setq flag t)
                (vla-put-scalefactor a (* (vla-get-scalefactor a) (/ 1.0 ratio)))
            )       
        )
        (if flag (vla-update block-reference))
    )
    (princ)
)

(defun c:Foo ( / block-spec tag-spec max-width ss i )

    (vl-load-com)

    ;;  please provide these values:

    (setq
        block-spec "OUR-TITLE-BLOCK-NAME"
        tag-spec   "TITLE*#*"
        [color=red]max-width  5.25[/color]
    )

    (if (setq ss (ssget "x" (list '(0 . "insert")'(66 . 1)(cons 2 block-spec))))
        (repeat (setq i (sslength ss))
            (mpx-restrict-attrib-widths
                (vlax-ename->vla-object (ssname ss (setq i (1- i))))
                tag-spec
                max-width
            )
        )
    )
   
    (princ)
   
)

Cheers.


I like how this works.
 .....       
       (if flag (vla-update block-reference))
    )
    (princ)
)

(defun c:ATTWIDTH ( / block-spec tag-spec max-width ss i )

    (vl-load-com)

   (setq dim1 (getvar 'dimscale));;get dimscale to multiply max-width variable to it.
   
    (setq
        block-spec "TBLK_ATT_CTL"
        tag-spec   "TITLELINE1"
       max-width  5.25 ;;how do I multiply this times the dimscale to use in scaled dwgs.

(if (setq ss (ssget "x" (list '(0 . "insert")'(66 . 1)(cons 2 block-spec)(max-width * (getvar 'dimscale))))));;I'm guessing here but can't seem to make anything stick
        (repeat (setq i (sslength ss))
            (mpx-restrict-attrib-widths
                (vlax-ename->vla-object (ssname ss (setq i (1- i))))
                tag-spec
                max-width
            )
        )
    )
   
    (princ)
   
)

J. Logan
ACAD2015
J. Logan
ACAD 2018

I am one with the Force and the Force is with me.
AutoCAD Map 2018 Windows 10

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Attributed text fit in bounding box
« Reply #13 on: April 12, 2018, 02:40:40 PM »
If I understood correctly perhaps this (coded bind / can't test from my current location):

Code: [Select]
(defun c:ATTWIDTH ( / block-spec tag-spec max-width ss i )

    (vl-load-com)

    (setq
        block-spec "TBLK_ATT_CTL"
        tag-spec   "TITLELINE1"
        ;;  how do I multiply this times the dimscale to use in scaled dwgs.
        max-width  (* 5.25 (getvar 'dimscale))
    )       

    (if (setq ss (ssget "x" (list '(0 . "insert")'(66 . 1)(cons 2 block-spec))))
        (repeat (setq i (sslength ss))
            (mpx-restrict-attrib-widths
                (vlax-ename->vla-object (ssname ss (setq i (1- i))))
                tag-spec
                max-width
            )
        )
    )
   
    (princ)
   
)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

jlogan02

  • Bull Frog
  • Posts: 327
Re: Attributed text fit in bounding box
« Reply #14 on: April 12, 2018, 03:51:29 PM »
Thanks MP. that works justtt fine.

J. Logan
ACAD 2018

I am one with the Force and the Force is with me.
AutoCAD Map 2018 Windows 10