Find attribute's block owner....

Discussion in 'AutoCAD' started by James Maeding, Feb 9, 2005.

  1. I have a prog that uses nentsel to grab things and list the properties.
    For eerything but attributes, nentsel gives a trail of info on nested items.

    I need to construct that trail for attributes.

    I thought about reissuing the entsel for the same point picked as the nentsel command to get the block name, but you
    cannot feed entsel a point to my knowlege. On top of that, it would not give a decent trail for items nested several
    times..

    I think the way to do this is to make a vla object from the attribute ename, then use the Object ID property to step
    back through to the top.

    Anyone done this before in lisp? (that cares to share :)
    thanks
    James Maeding
    jmaeding at hunsaker dot com
    Civil Engineer/Programmer
     
    James Maeding, Feb 9, 2005
    #1
  2. Good call. If I'm not mistaken though there can be multiple
    330 groups (e.g. reactor) so one might need to do a little
    more processing.
     
    Michael Puckett, Feb 9, 2005
    #2
  3. thanks for the replies, I had not looked at the sequend
    thx

    James Maeding <jmaeding at hunsaker dot com>
    |>I have a prog that uses nentsel to grab things and list the properties.
    |>For eerything but attributes, nentsel gives a trail of info on nested items.
    |>
    |>I need to construct that trail for attributes.
    |>
    |>I thought about reissuing the entsel for the same point picked as the nentsel command to get the block name, but you
    |>cannot feed entsel a point to my knowlege. On top of that, it would not give a decent trail for items nested several
    |>times..
    |>
    |>I think the way to do this is to make a vla object from the attribute ename, then use the Object ID property to step
    |>back through to the top.
    |>
    |>Anyone done this before in lisp? (that cares to share :)
    |>thanks
    |>James Maeding
    |>jmaeding at hunsaker dot com
    |>Civil Engineer/Programmer

    James Maeding
    jmaeding at hunsaker dot com
    Civil Engineer/Programmer
     
    James Maeding, Feb 9, 2005
    #3
  4. oh, slick, I see now what Herman is saying, the 330 group is the parent ename.
    I guess I can just watch for group 102s that seem to start and end reactor dxf codes.
    thanks all

    James Maeding <jmaeding at hunsaker dot com>
    |>I have a prog that uses nentsel to grab things and list the properties.
    |>For eerything but attributes, nentsel gives a trail of info on nested items.
    |>
    |>I need to construct that trail for attributes.
    |>
    |>I thought about reissuing the entsel for the same point picked as the nentsel command to get the block name, but you
    |>cannot feed entsel a point to my knowlege. On top of that, it would not give a decent trail for items nested several
    |>times..
    |>
    |>I think the way to do this is to make a vla object from the attribute ename, then use the Object ID property to step
    |>back through to the top.
    |>
    |>Anyone done this before in lisp? (that cares to share :)
    |>thanks
    |>James Maeding
    |>jmaeding at hunsaker dot com
    |>Civil Engineer/Programmer

    James Maeding
    jmaeding at hunsaker dot com
    Civil Engineer/Programmer
     
    James Maeding, Feb 9, 2005
    #4
  5. Here's a quick stab at a Visual LISP GetOwner function. In my
    travels I've found that an OwnerID of 0 means the object's
    document. If I'm wrong I'd like to hear about it. Thanks.

    Code:
    
    (defun GetOwner ( object / ownerID result )
    (if
    (null
    (vl-catch-all-error-p
    (setq result
    (vl-catch-all-apply
    '(lambda ()
    (if
    (zerop
    (setq ownerID
    (vlax-get-property
    object
    'OwnerID
    )
    )
    )
    (vlax-get-property
    object
    'Document
    )
    (vlax-invoke-method
    (vlax-get-property
    object
    'Document
    )
    'ObjectIdToObject
    ownerID
    )
    )
    )
    )
    )
    )
    )
    result
    )
    )
    
    
     
    Michael Puckett, Feb 9, 2005
    #5
  6. Bizarro timing, see post below.
     
    Michael Puckett, Feb 9, 2005
    #6
  7. hmm, even knowing how to get parent of attrib or ObjectID, this is still tricky.

    I started writing a function called ENTITY-TRAIL.
    I want it to take an entity name (any entity) in and spit out the trail of entity names up to the top.

    If I try the ObjectID method, I am not sure how to get an object based on an ID value, the item method of modelspace
    does not take an ID as an argument, only an index.
    I dont wat to loop through the entire database to find the object that way.

    If I try the lisp method, I dont know how to get the parent (insert) if a non-attrbute is picked.
    the 330 of an attribute give the ename for the parent insert.
    The 330 of a nested circle (for instance) gives the block definition record from the block table, and I need the insert
    entity. Its like it gets skipped.
    So I cannot figure out the parent insert of a non-attribute so far.

    Any ideas?


    James Maeding <jmaeding at hunsaker dot com>
    |>I have a prog that uses nentsel to grab things and list the properties.
    |>For eerything but attributes, nentsel gives a trail of info on nested items.
    |>
    |>I need to construct that trail for attributes.
    |>
    |>I thought about reissuing the entsel for the same point picked as the nentsel command to get the block name, but you
    |>cannot feed entsel a point to my knowlege. On top of that, it would not give a decent trail for items nested several
    |>times..
    |>
    |>I think the way to do this is to make a vla object from the attribute ename, then use the Object ID property to step
    |>back through to the top.
    |>
    |>Anyone done this before in lisp? (that cares to share :)
    |>thanks
    |>James Maeding
    |>jmaeding at hunsaker dot com
    |>Civil Engineer/Programmer

    James Maeding
    jmaeding at hunsaker dot com
    Civil Engineer/Programmer
     
    James Maeding, Feb 9, 2005
    #7
  8. oh, posted my response too soon,
    now I see the ObjectIdToObject method in Mr Puckett's code.
    Thanks Michael!

    James Maeding <jmaeding at hunsaker dot com>
    |>hmm, even knowing how to get parent of attrib or ObjectID, this is still tricky.
    |>
    |>I started writing a function called ENTITY-TRAIL.
    |>I want it to take an entity name (any entity) in and spit out the trail of entity names up to the top.
    |>
    |>If I try the ObjectID method, I am not sure how to get an object based on an ID value, the item method of modelspace
    |>does not take an ID as an argument, only an index.
    |>I dont wat to loop through the entire database to find the object that way.
    |>
    |>If I try the lisp method, I dont know how to get the parent (insert) if a non-attrbute is picked.
    |>the 330 of an attribute give the ename for the parent insert.
    |>The 330 of a nested circle (for instance) gives the block definition record from the block table, and I need the insert
    |>entity. Its like it gets skipped.
    |>So I cannot figure out the parent insert of a non-attribute so far.
    |>
    |>Any ideas?
    |>
    |>
    |>James Maeding <jmaeding at hunsaker dot com>
    |>|>I have a prog that uses nentsel to grab things and list the properties.
    |>|>For eerything but attributes, nentsel gives a trail of info on nested items.
    |>|>
    |>|>I need to construct that trail for attributes.
    |>|>
    |>|>I thought about reissuing the entsel for the same point picked as the nentsel command to get the block name, but you
    |>|>cannot feed entsel a point to my knowlege. On top of that, it would not give a decent trail for items nested several
    |>|>times..
    |>|>
    |>|>I think the way to do this is to make a vla object from the attribute ename, then use the Object ID property to step
    |>|>back through to the top.
    |>|>
    |>|>Anyone done this before in lisp? (that cares to share :)
    |>|>thanks
    |>|>James Maeding
    |>|>jmaeding at hunsaker dot com
    |>|>Civil Engineer/Programmer
    |>
    |>James Maeding
    |>jmaeding at hunsaker dot com
    |>Civil Engineer/Programmer

    James Maeding
    jmaeding at hunsaker dot com
    Civil Engineer/Programmer
     
    James Maeding, Feb 9, 2005
    #8
  9. Well, you're hearing about it. :)

    Non-database resident objects can be exposed via ActiveX
    (As of AutoCAD 2004 / 2005,) and their ObjectID is always 0.
     
    Tony Tanzillo, Feb 9, 2005
    #9
  10. Good point Tony. When you have time can you provide
    an example of a non resident object? You mean like
    a menubar object or an xrecord that doesn't have an
    owner yet ... something along those lines?

    Thinking briefly, this means the document property
    would be invalid, and as a result, they way GetOwner
    function is coded it should return nil (the document
    object would be nil and / or the call to the
    ObjectIdToObject method would chuck a wobbly). If not
    one should be able to trap that condition and return
    nil.

    Thoughts?

    Thank you.
     
    Michael Puckett, Feb 9, 2005
    #10
  11. Turns out an xrecord is a good exmaple. When newly
    created it does not have an owner, and its OwnerID
    is 0. Its 330 looks like (330 . <Entity name: 0>).
     
    Michael Puckett, Feb 9, 2005
    #11
  12. If one cannot assume an OwnerID of 0 is always the
    document object, or that the document object is the
    owner then perhaps all that is needed is this ...

    Code:
    
    (defun GetOwner ( object / result )
    (if
    (null
    (vl-catch-all-error-p
    (setq result
    (vl-catch-all-apply
    '(lambda ()
    (vlax-invoke-method
    (vlax-get-property
    object
    'Document
    )
    'ObjectIdToObject
    (vlax-get-property
    object
    'OwnerID
    )
    )
    )
    )
    )
    )
    )
    result
    )
    )
    
    
     
    Michael Puckett, Feb 9, 2005
    #12
  13. Any object (AcadObject or descendent) can be exposed
    via ActiveX without it being database resident. Often,
    they are newly created objects that are being used on
    a temporary basis for various operations (e.g., dragging),
    and are deleted when they're no longer needed.

    An example of how I might use them, is to allow high-
    level ActiveX clients to do dragging of new objects
    before they're actually appended to the database.
     
    Tony Tanzillo, Feb 9, 2005
    #13
  14. The first 330 group is always the owner, so a simple call
    to (assoc 330 ..) will always return the owner id.
     
    Tony Tanzillo, Feb 9, 2005
    #14
  15. I finished my routine and thought it would work, but it seems that I cannot get the object id of an object in an xref.
    This is because the document property is not available for the object.
    Is this the same thing Tony was talking about?
    If so, was there a recommended way of getting the info from an xref.
    I guess we could go the objectdbx route, but this is getting complicated...whatever it takes though.

    Here is the code I am using:
    test with (ENTITY-TRAIL (CAR (NENTSEL)))

    ;ATTRIBUTE TRAIL
    ;SPECIAL THANKS TO MICHAEL PUCKETT!
    ;RETURNS LIST OF ENAMES FROM ATTRIBUTE ON UP TO BLOCKS CONTAINING IT
    ;(ENTITY-TRAIL (CAR (NENTSEL)))

    (DEFUN ENTITY-TRAIL (ENAME / OBJ RET PARENT)
    ;MAKE OBJECT
    (SETQ OBJ (vlax-ename->vla-object ENAME)
    RET (LIST ENAME)
    )
    ;WHILE OBJECT ABOVE IS NOT A TABLE RECORD, LOOK FOR PARENTS
    (WHILE (AND (SETQ OBJ (GETOWNER OBJ))
    (/= (STRCASE (VLAX-GET-PROPERTY OBJ 'OBJECTNAME)) "ACDBBLOCKTABLERECORD")
    )
    (SETQ RET (CONS (vlax-vla-object->ename OBJ) RET))
    )
    (REVERSE RET)
    )

    ;GET OWNER FUNCTION
    (DEFUN GETOWNER ( OBJECT / OWNERID RESULT )
    (IF (NULL (VL-CATCH-ALL-ERROR-P
    (SETQ RESULT
    (VL-CATCH-ALL-APPLY
    '(LAMBDA ()
    (IF (ZEROP (SETQ OWNERID (VLAX-GET-PROPERTY OBJECT 'OWNERID)))
    (VLAX-GET-PROPERTY OBJECT 'DOCUMENT)
    (VLAX-INVOKE-METHOD (VLAX-GET-PROPERTY OBJECT 'DOCUMENT)
    'OBJECTIDTOOBJECT
    OWNERID
    )
    )
    )
    )
    )
    )
    )
    RESULT
    )
    )

    James Maeding <jmaeding at hunsaker dot com>
    |>I have a prog that uses nentsel to grab things and list the properties.
    |>For eerything but attributes, nentsel gives a trail of info on nested items.
    |>
    |>I need to construct that trail for attributes.
    |>
    |>I thought about reissuing the entsel for the same point picked as the nentsel command to get the block name, but you
    |>cannot feed entsel a point to my knowlege. On top of that, it would not give a decent trail for items nested several
    |>times..
    |>
    |>I think the way to do this is to make a vla object from the attribute ename, then use the Object ID property to step
    |>back through to the top.
    |>
    |>Anyone done this before in lisp? (that cares to share :)
    |>thanks
    |>James Maeding
    |>jmaeding at hunsaker dot com
    |>Civil Engineer/Programmer

    James Maeding
    jmaeding at hunsaker dot com
    Civil Engineer/Programmer
     
    James Maeding, Feb 9, 2005
    #15
  16. can't you use

    (cdr
    (assoc 330
    (entget ename)
    )
    )

    ...

    and on up the food chain up to the space (paper/model) the
    object is a child of?
     
    Michael Puckett, Feb 9, 2005
    #16
  17. I'll try again, but when I tried it last, it does not give the insert object when I do that for a non-attribute.
    It acts differently for attributes and lines/arcs.
    Thats why the object method looked nice.

    I'll try some more.

    "Michael Puckett" <>
    |>can't you use
    |>
    |> (cdr
    |> (assoc 330
    |> (entget ename)
    |> )
    |> )
    |>
    |> ...
    |>
    |>and on up the food chain up to the space (paper/model) the
    |>object is a child of?
    |>

    James Maeding
    jmaeding at hunsaker dot com
    Civil Engineer/Programmer
     
    James Maeding, Feb 10, 2005
    #17
  18. Here is what I have found to work best so far:

    if a non-attribute was picked, use the info from the nentsel, simple.

    If an attribute was picked, use the 330 code to step back.

    The only problem is that stepping back with 330 does not give what nentsel did.

    the 330 gives (for an attribute):
    the attribute
    the insert
    the block record
    the block table

    while nentsel gives (for a non-attribute):
    the attribute
    the insert
    the xref

    So the 330 method gets derailed right after the insert item.
    I am so close...

    James Maeding <jmaeding at hunsaker dot com>


    James Maeding
    jmaeding at hunsaker dot com
    Civil Engineer/Programmer
     
    James Maeding, Feb 10, 2005
    #18
  19. ok, new idea, when I get to the block record using the 330 method, I will look up the name of the xref from the block
    name, then cut off the loop and find the xref with other means (tblobjname) I think.
    Its amazing how complicated this got all because nentsel behaves differently for attributes....

    James Maeding <jmaeding at hunsaker dot com>
    |>Here is what I have found to work best so far:
    |>
    |>if a non-attribute was picked, use the info from the nentsel, simple.
    |>
    |>If an attribute was picked, use the 330 code to step back.
    |>
    |>The only problem is that stepping back with 330 does not give what nentsel did.
    |>
    |>the 330 gives (for an attribute):
    |>the attribute
    |>the insert
    |>the block record
    |>the block table
    |>
    |>while nentsel gives (for a non-attribute):
    |>the attribute
    |>the insert
    |>the xref
    |>
    |>So the 330 method gets derailed right after the insert item.
    |>I am so close...
    |>
    |>James Maeding <jmaeding at hunsaker dot com>
    |>
    |>
    |>James Maeding
    |>jmaeding at hunsaker dot com
    |>Civil Engineer/Programmer

    James Maeding
    jmaeding at hunsaker dot com
    Civil Engineer/Programmer
     
    James Maeding, Feb 10, 2005
    #19
  20. James Maeding

    T.Willey Guest

    Do you want something like this?

    Tim

    (defun c:GetTrail (/ Ent EntData EntType LastEnt LastEntData LastEntType LastEntPath EndList)

    (if (setq Ent (nentsel))
    (progn
    (setq LastEnt (car (last Ent)))
    (setq Ent (car Ent))
    (setq EntData (entget Ent))
    (setq EntType (cdr (assoc 0 EntData)))
    (while (/= EntType "BLOCK_RECORD")
    (setq EndList (cons (list Ent EntType) EndList))
    (setq Ent (cdr (assoc 330 EntData)))
    (setq EntData (entget Ent))
    (setq EntType (cdr (assoc 0 EntData)))
    )
    (if (= (type LastEnt) 'ENAME)
    (progn
    (setq LastEntData (entget LastEnt))
    (setq LastEntType (cdr (assoc 0 LastEntData)))
    (if (setq LastEntPath (cdr (assoc 1 (tblsearch "block" (cdr (assoc 2 LastEntData))))))
    (setq EndList (cons (list LastEnt LastEntType (strcat "XrPath - " LastEntPath)) EndList))
    (setq EndList (cons (list LastEnt LastEntType) EndList))
    )
    )
    )
    )
    )
    EndList
    )
     
    T.Willey, Feb 10, 2005
    #20
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.