Author Topic: Add attributes one the fly  (Read 19112 times)

0 Members and 1 Guest are viewing this topic.

T.Willey

  • Needs a day job
  • Posts: 5251
Add attributes one the fly
« on: December 13, 2005, 01:04:33 PM »
I have searched and didn't find what I was looking for, or maybe I just didn't understand fully what I was reading, but here is my question.

I was wondering how you would add attributes one the fly? No code needed just theory.  It looks like some people were re-entmake'ing the block, and then entmake'ing attributes, and then entmake'ing the seqend object, is this the only way?

I'm just a little lost.

Thanks in advance.
Tim
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: Add attributes one the fly
« Reply #1 on: December 13, 2005, 01:31:42 PM »
Well, if you are wanting to add attributes to existing blocks.....this is how I'd approach it:
1. Forget (entmake)(entmod)
2. Recall ActiveX
3. Add the attribute to the block def
4. Collect SS of any inserts
5. Insert new block at each exist insert & set att's & props to match old
6. Check if any Xdata attached and copy if so,
7. Delete the old block

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Add attributes one the fly
« Reply #2 on: December 13, 2005, 01:37:40 PM »
3. Add the attribute to the block def

I was hoping to do this without changing the block definition.  I was looking at doing it as a "per block" instance.

Tim
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: Add attributes one the fly
« Reply #3 on: December 13, 2005, 02:21:33 PM »
OK, to be honest I'd never thought of doing this and so didn't know it was possible. But after a bit of testing, it looks like the method you describe is the only way without going to ObjectARX.

If you'd like to see my sample code, just holler.....

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Add attributes one the fly
« Reply #4 on: December 13, 2005, 02:30:19 PM »
Thanks for the conformation Jeff.  Let me see what I can come up with, and then I will look at yours to see how much better it is.

Now all I have to figure out is what are the necessary dxf codes to create a block on the fly.  I always mess that up.

Thanks as always.
Tim
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Jürg Menzi

  • Swamp Rat
  • Posts: 599
  • Oberegg, Switzerland
Re: Add attributes one the fly
« Reply #5 on: December 13, 2005, 03:12:08 PM »
Hmmm... I had a similar problem.
To solve that, I've copied the block definition by 'VxCloneBlockRef' (see my homepage -> Free Stuff) to a new (random) name. Then add the additional object(s) to the copied definition. Finally I had only to set the concerned insert to the new name. 8-)
A computer's human touch is its unscrupulousness!
MENZI ENGINEERING GmbH
Current A2k16... A2k24 - Start R2.18

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Add attributes one the fly
« Reply #6 on: December 13, 2005, 06:33:56 PM »
Okay.  Here is my code, that seems to work on my testing here.  Fun little exercise.  Any comments welcomed.  It will add attributes to xref's also.
Code: [Select]
(defun VALUE (num ent /)
  (cdr (assoc num ent))
)

(defun c:AddExtraAtt (/ Sel EntData tmpEnt Tag Str Just tmpOpt Just72 Just73 InsPt Rot Ht
                        flag CreateAtt ActDoc Sel2 *error*)

; Add attributes until you hit enter to an existing block, while keeping the original attributes.
; Tim Willey 12/2005
; Sub's 'CreateAtt 'value
; Thanks to Jeff Mishler and Kerry Brown at www.theswamp.org for their input.

(defun *error* (msg)
 (princ msg)
 (vla-EndUndoMark ActDoc)
 (if Sel
  (redraw (car Sel) 4)
 )
)

(defun CreateAtt (Tag Str InsPt Just72 Just73 Ht Rot / )

(entmake
 (list
  (cons 0 "ATTRIB")
  (cons 100 "AcDbEntity")
  (cons 100 "AcDbText")
  (cons 100 "AcDbAttribute")
  (cons 1 Str)
  (cons 2 Tag)
  (cons 6 "ByBlock")
  (cons 8 "0")
  (cons 10 InsPt)
  (cons 11 InsPt)
  (cons 40 Ht)
  (cons 50 Rot)
  (cons 62 256)
  (cons 70 0)
  (cons 72 Just72)
  (cons 73 Just73)
 )
)
)

(setq ActDoc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
(vla-StartUndoMark ActDoc)
(if
 (and
  (setq Sel (entsel "\n Select block to add attribute to: "))
  (setq EntData (entget (car Sel)))
  (= (value 0 EntData) "INSERT")
  (not (redraw (car Sel) 3))
 )
 (progn
  (if (not (assoc 66 EntData))
   (entmake (append EntData (list (cons 66  1))))
   (entmake EntData)
  )
  (setq tmpEnt (car Sel))
  (if
   (and
    (entnext tmpent)
    (= (cdr (assoc 0 (entget (entnext tmpent)))) "ATTRIB")
   )
   (while (/= (value 0 (entget (setq tmpEnt (entnext tmpEnt)))) "SEQEND")
    (entmake (setq EntData (entget tmpEnt)))
   )
   (setq flag T)
  )
  (while
   (and
    (not (initget "Type"))
    (setq Sel2 (nentsel "\n Select existing attribute to match, or Type in attribute properties: "))
    (if (= Sel2 "Type")
     (progn
      (setq InsPt (getpoint "\n Select insertion point: "))
      (setq Ht (getdist "\n Height of attribute: "))
      (setq Rot (getangle "\n Rotation of attribute: "))
      (/= (setq Tag (getstring T "\n Enter tag value: ")) "")
      (/= (setq Str (getstring T "\n Enter displayed value: ")) "")
      (not (initget "L C R M TL TC TR ML MC MR BL BC BR"))
      (setq Just
       (if (setq tmpOpt (getkword "\n Justification [<L>/C/R/M/TL/TC/TR/ML/MC/MR/BL/BC/BR]: "))
        tmpOpt
        "L"
       )
      )
      (cond
       ((= Just "L")
        (setq Just72 0)
        (setq Just73 0)
       )
       ((= Just "C")
        (setq Just72 1)
        (setq Just73 0)
       )
       ((= Just "R")
        (setq Just72 2)
        (setq Just73 0)
       )
       ((= Just "M")
        (setq Just72 4)
        (setq Just73 0)
       )
       ((= Just "TL")
        (setq Just72 0)
        (setq Just73 3)
       )
       ((= Just "TC")
        (setq Just72 1)
        (setq Just73 3)
       )
       ((= Just "TR")
        (setq Just72 2)
        (setq Just73 3)
       )
       ((= Just "ML")
        (setq Just72 0)
        (setq Just73 2)
       )
       ((= Just "MC")
        (setq Just72 1)
        (setq Just73 2)
       )
       ((= Just "MR")
        (setq Just72 2)
        (setq Just73 2)
       )
       ((= Just "BL")
         (setq Just72 0)
        (setq Just73 1)
       )
       ((= Just "BC")
        (setq Just72 1)
        (setq Just73 1)
       )
       ((= Just "BR")
        (setq Just72 2)
        (setq Just73 1)
       )
      )
     )
     (progn
      (setq InsPt (getpoint "\n Select insertion point: "))
      (/= (setq Tag (getstring T "\n Enter tag value: ")) "")
      (/= (setq Str (getstring T "\n Enter displayed value: ")) "")
      (setq Just72 (value 72 (entget (car Sel2))))
      (setq Just73 (value 73 (entget (car Sel2))))
      (setq Ht (value 40 (entget (car Sel2))))
      (setq Rot (value 50 (entget (car Sel2))))
     )
    )
   )   
   (CreateAtt Tag Str InsPt Just72 Just73 Ht Rot)
  )
  (if flag
   (entmake
    (list
     (cons 0 "SEQEND")
     (cons 100 "AcDbEntity")
     (cons 8 (value 8 EntData))
    )
   )
   (entmake (setq EntData (entget tmpEnt)))
  )
  (entdel (car Sel))
 )
)
(vla-EndUndoMark ActDoc)
(princ)
)
Tim

Updated per Jeff's code
Updated per Kerry's post
Update code.  Added error trap, and the ability to select attribute to match height, rotation and justification properties.
« Last Edit: December 14, 2005, 02:43:31 PM by T.Willey »
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: Add attributes one the fly
« Reply #7 on: December 13, 2005, 07:07:05 PM »
Looks good to me, Tim. The only thing I can find to recommend is that if the user selects something other than a block you will get some unexpected behavior. I would add a check immediately after the (entsel) to verify that a Block was selected. Something like this:
Code: [Select]
(if (and (setq Sel (entsel "\ Select block to add attribute to: "))
(setq EntData (entget (car Sel)))
(eq (cdr (assoc 0 EntData)) "INSERT")
)
(progn
  ;;(setq EntData (entget (car Sel)));;this was moved up
  (if (not (assoc 66 EntData))
Good Job!

CADaver

  • Guest
Re: Add attributes one the fly
« Reply #8 on: December 13, 2005, 07:09:18 PM »
What happens if the block is ATTSYNC'd later?

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Add attributes one the fly
« Reply #9 on: December 13, 2005, 07:12:58 PM »
Thanks Jeff.  I usually do that, but had it that way when coding and testing, but forgot to change this one.  Care to share your code now?  I like seeing how others do things, so that I can learn.  I will change the one I have here, and I guess I can change the code I posted also.

Tim

ps.
CADaver,

  I don't use ATTSYNC, but I don't think there is anyway to keep it from getting lost with attsync because I don't want to change the blocks definition in the blocks collection (table).  Maybe someone else would like to share.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: Add attributes one the fly
« Reply #10 on: December 13, 2005, 07:39:35 PM »
Tim,
The code I had was just some tinkering to see what could be done. Instead of asking for the text size/rotation I copied an existing attribute (not much use when the block doesn't have any) and only input the Tag/Text strings. But again, I wasn't trying to come up witha solution as you have done.....I was curious if it could be done..... And somewhere along the line today I closed that session without saving my doodlings.

ATTSYNC, In the past 15 years I've used it once. Oh, and welcome back Randy!

Just out of curiosity....what is the purpose of adding an attribute to a block in this fashion? I've tried to think of a scenario that I could utilize this, but have come up empty.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Add attributes one the fly
« Reply #11 on: December 13, 2005, 07:42:39 PM »
Hi Tim,

Looks fine to me.
Recommendation to polish :
ActDoc variable could be local
Add an error trap to ensure (vla-EndUndoMark ActDoc) is called if the user dummy-spits.

Interesting alternative : If you have a bit of time < hehehe > having an ActiveX <vla-..> version to compare may be interesting.

ditto Jeff's usage comment ^ ^



kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: Add attributes one the fly
« Reply #12 on: December 13, 2005, 07:59:56 PM »
< hehehe > having an ActiveX <vla-..> version to compare may be interesting.
He might need a bunch of time Kerry. I haven't researched beyond this snip in the Docs:
Quote from: ActiveX AttRef Help
You cannot directly create an attribute reference. Attribute references are added to the drawing when a block containing an attribute definition is inserted into the drawing.
but if you have any ideas....:)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Add attributes one the fly
« Reply #13 on: December 13, 2005, 08:40:46 PM »
Must admit I haven't tried making attributed blocks with the ActiveX Library Jeff .. just conventional blocks.


.. I'm still having difficulty coming to terms with the original post idea of having blocks with the same name having different definitions.
The hairs on the back of my neck are standing up.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

whdjr

  • Guest
Re: Add attributes one the fly
« Reply #14 on: December 14, 2005, 07:11:06 AM »
.. I'm still having difficulty coming to terms with the original post idea of having blocks with the same name having different definitions.
The hairs on the back of my neck are standing up.

That's a big DITTO!!!!  You have all kinds of troubles with your blocks then which is what randy was trying to say.  If you change a block and add an attribute to it, then the only way (even after redefining the block) for the previously inserted block defs to have the correct attributes is an attsync.



Welcome back Randy  :-)