Why does Entlast not work?

Discussion in 'AutoCAD' started by Kiwi Russ, Jan 31, 2004.

  1. Kiwi Russ

    Kiwi Russ Guest

    The lisp below draws a rectangle and places a centroid cross. My test
    lisp previously worked well using entsel. However now I have modified it so
    that an entity is drawn (in this case a rectangle) and I have used (setq e6
    (entlast)) to obtain entity properties. In the vlax properties there is no
    mention of 'centroid'. What am I doing wrong?
    thanks Russ

    (defun c:testcent(/)
    (setq sf 50)
    (setq pt1 '(0 0 0))
    (setq pt2 (polar pt1 0 3000))
    (setq pt3 (polar pt2 (* 0.5 pi) 1000))
    (setq pt4 (polar pt3 (* 1.0 pi) 3000))
    (command "pline" pt1 pt2 pt3 pt4 "")
    (setq e6 (entlast))
    (setq vname3 (vlax-ename->vla-object e6 ))
    (vla-GetBoundingBox vname3 'Pt1c 'Pt3c)
    (setq Pt1c (vlax-safearray->list Pt1c)
    Pt3c (vlax-safearray->list Pt3c)
    );setq
    (command "_.COPY" e6 "" '(0 0 0) '(0 0 0)
    "_.LAYER" "_MAKE" "TmpInnObj" "" ;
    );command
    (command "color" "White")
    (command "_.EXTRUDE" e6 "" WidthSt 0)
    (setvar "OSMODE" 0)
    (setq PanObj3 (vlax-ename->vla-object (entlast)));convert temporary
    entity to object
    (vla-GetBoundingBox PanObj3 'Pt1c 'Pt3c);get bounding box of object
    (setq Pt3c (vlax-safearray->list Pt3c);convert upper right and
    Pt1c (vlax-safearray->list Pt1c);lower left point to list
    DstLst3 (mapcar '- Pt3c Pt1c);get X- and Y- distances
    OriCen3 (vlax-safearray->list;convert centroid to list
    (vlax-variant-value;convert centroid to variant
    (vla-get-Centroid PanObj3);get centroid from object
    )
    )
    CurCen3 (mapcar '- OriCen3 Pt1c);calculate centroid offset
    CenTxt3 (apply;apply prefixes to
    'strcat;centroid value
    (mapcar '(lambda (l1 l2)(strcat l1 (rtos l2 2 0));format centroid
    numbers
    ) TmpLst CurCen3
    )
    )
    SeLoop nil ;reset loop
    );setq
    (vla-Erase PanObj3)
    (setq CenPt3 (list(car OriCen3) (cadr OriCen3)));Strip 'z' value for
    center point insertion
    (setvar "OSMODE" 0);OSMODE
    (if (tblsearch "LAYER" "TmpInnObj");if temporary layer, then...
    (command "_.PURGE" "_LAY" "TmpInnObj" "_NO")
    );if
    (setvar "OSMODE" 0)
    (command "_.INSERT" "PanelCenter" CenPt3 sf "" 0);insert centroid mark
    );defun
     
    Kiwi Russ, Jan 31, 2004
    #1
  2. Kiwi Russ

    TCEBob Guest

    Gosh, Kiwi, that seems like a lot of heavy hauling for a simple task. As
    far as horizontal rectangles are concerned, centroids are easy. If you
    are after bigger game check out MASSPROP. I don't know how to directly
    break out the centroid, you may have to write out to a temporary file
    and then extract the info.

    Could you post a sketch of what you are after?

    rs
     
    TCEBob, Jan 31, 2004
    #2
  3. Kiwi Russ

    Joe Burke Guest

    Hi Russ,

    I can't see what's wrong, but I don't think the problem is related to entlast. I drew
    a pline and extruded it. Then:

    Command: (setq vobj (vlax-ename->vla-object (entlast)))
    #<VLA-OBJECT IAcad3DSolid 0f6258b4>

    Command: (vlax-get vobj 'Centroid)
    (204721.0 -246578.0 4.9507) ;returns a point

    Command: (vla-get-centroid vobj)
    #<variant 8197 ...> ;returns a variant

    Notice, in many cases you can eliminate fussing with variants and safearrays using
    the "vlax-get" function/style rather than "vla-get-propertyname".

    Likewise with "vlax-put" vobj 'QuotedPropertyName Data. Data in this case is much
    more forgiving. If Data makes sense in terms of the property you want to apply it to,
    the function will probably work.

    For instance draw a line starting at 0,0. Then:

    Command: (setq vobj (vlax-ename->vla-object (entlast)))
    #<VLA-OBJECT IAcadLine 0f6c8194>

    Command: (vlax-put vobj 'StartPoint '(1.0 1.0 0.0))
    nil

    Command: (vlax-get vobj 'StartPoint)
    (1.0 1.0 0.0) ;ok

    But not the following because "vla-put-StartPoint" wants a variant argument.

    Command: (vla-put-StartPoint vobj '(2.0 2.0 0.0))
    ; error: lisp value has no coercion to VARIANT with this type: (2.0 2.0 0.0)

    This will work, but why bother?

    Command: (vla-put-StartPoint vobj (vlax-3D-point '(2.0 2.0 0.0)))
    nil

    Command: (vlax-get vobj 'StartPoint)
    (2.0 2.0 0.0) ;ok

    HTH and glad to see you took the vlisp/ActiveX plunge. :)

    Regards
    Joe Burke
     
    Joe Burke, Jan 31, 2004
    #3
  4. Kiwi Russ

    favline Guest

    I believe, there are so many things you have to
    check, before baking your bread..:)

    1. variable WidthSt is not defined.
    2. thus, extrude command may not work
    3. thus, entlast refers to the pline and not
    the solid.
    4. thus, vla-object panobj3 refers to a pline
    5. Unfortunately, pline don't have centroid
    property in the programming language
    you're using.

    Just my 2 cents. I might be wrong......
     
    favline, Jan 31, 2004
    #4
  5. Kiwi Russ

    Kiwi Russ Guest

    oops sorry I hadn't supplied the line
    (setq WidthSt 2000)
    at the very first line.
    However this still doesn't seem to work.
    Entlast I reckon is still the problem.......
     
    Kiwi Russ, Jan 31, 2004
    #5
  6. Kiwi Russ

    Kiwi Russ Guest

    Thanks Joe for the explanation. Though I'm still not sure quite whats going
    on.
    The code below is similar to what I had before, however this time I am using
    entsel on an object that is already drawn (rather than entlast). It works
    fine, so how come?

    (defun c:testcent(/)
    (setq WidthSt 2000)
    (setq sf 50)
    (cond
    ((not (setq e6 (car (entsel "\nSelect outline : ")))))
    ((/= (cdr (assoc 0 (setq eprPline3(entget e6)))) "LWPOLYLINE")
    (alert "Selected object is not a polyline."))
    (T
    (setq vname3 (vlax-ename->vla-object e6 ))
    (vla-GetBoundingBox vname3 'Pt1c 'Pt3c)
    (setq Pt1c (vlax-safearray->list Pt1c);Lower Left points of
    Bounding box
    Pt3c (vlax-safearray->list Pt3c);Upper Right points of
    Bounding box
    );setq
    (command "_.COPY" e6 "" '(0 0 0) '(0 0 0)
    "_.LAYER" "_MAKE" "TmpInnObj" ""
    );command
    (command "_.EXTRUDE" e6 "" WidthSt 0)
    (setvar "OSMODE" 0)
    (setq PanObj3 (vlax-ename->vla-object (entlast)));convert temporary
    entity to object
    (vla-GetBoundingBox PanObj3 'Pt1c 'Pt3c);get bounding box of object
    (setq Pt3c (vlax-safearray->list Pt3c);convert upper right and
    Pt1c (vlax-safearray->list Pt1c);lower left point to list
    DstLst3 (mapcar '- Pt3c Pt1c);get X- and Y- distances
    OriCen3 (vlax-safearray->list;convert centroid to list
    (vlax-variant-value;convert centroid to variant
    (vla-get-Centroid PanObj3)));get centroid from object
    CurCen3 (mapcar '- OriCen3 Pt1c);calculate centroid offset
    CenTxt3 (apply
    'strcat
    (mapcar
    '(lambda (l1 l2)
    (strcat l1 (rtos l2 2 0));format centroid numbers
    ) TmpLst CurCen3))
    SeLoop nil
    );setq
    (vla-Erase PanObj3);delete temporary object
    (setq CenPt3 (list(car OriCen3) (cadr OriCen3)));Strip 'z' value for
    center point insertion
    (setvar "OSMODE" 0)
    (command "_.INSERT" "PanelCenter" CenPt3 sf "" 0)
    );T
    );cond
    );defun
     
    Kiwi Russ, Jan 31, 2004
    #6
  7. Kiwi Russ

    ECCAD Guest

    You could try:

    (setq PanObj3 (vlax-ename->vla-object (entget (entlast))))

    Bob
     
    ECCAD, Jan 31, 2004
    #7
  8. Kiwi Russ

    Kiwi Russ Guest

    Thanks Bob
    but that does not work
     
    Kiwi Russ, Jan 31, 2004
    #8
  9. Kiwi Russ

    ECCAD Guest

    Could it be that the (command "_EXTRUDE"...
    (really) doesn't 'create' a 'new' entity, and, therefore, is not the 'entlast' ?

    Bob
     
    ECCAD, Jan 31, 2004
    #9
  10. Kiwi Russ

    Jeff Mishler Guest

    Well, yes and no.

    In one place I think you want to use (entlast), in the extrude line, you use
    e6.
    But your biggest problem is........you cannot extrude an open polyline.

    Try fixing the line you creat the polyline to:
    (command "pline" pt1 pt2 pt3 pt4 "c" "")

    and the extrude line, that is if you want to extrude the copied pline, to:
    (command "_.EXTRUDE" (entlast) "" WidthSt 0)

    Jeff
     
    Jeff Mishler, Jan 31, 2004
    #10
  11. Kiwi Russ

    Mark Propst Guest

    I'm thinking you probably meant
    (setq PanObj3 (vlax-ename->vla-object (entlast)))
    :)
     
    Mark Propst, Jan 31, 2004
    #11
  12. Kiwi Russ

    Mark Propst Guest

    Hi Russ,
    fwiw
    most of the time i've wasted degugging programs was spent because I assumed
    something was true when it wasn't
    one little debug technique is to make sure about what happened earlier in
    the prog before going on to further steps in the prog

    a possible thing to check in this case could be something like:
    (setq lastObject (vlax-ename->vla-object (entlast)));
    (setq objname(vlax-get-property lastobject 'objectname))
    (if ( = objname "AcDb3dSolid" )
    (print"safe to proceed")
    (print"something unexpected occurred")
    )

    another generalized check since you're getting into the vl funcs is to see
    if a property is available on the object, before trying to access it
    eg:
    (setq lastObject (vlax-ename->vla-object (entlast)));
    (if
    (vlax-property-available-p lastobject 'centroid)
    (print"Last object has a centoid property")
    (print"Last object doesn't have a centoid property")
    )


    another general technique it to go ahead with your assumptions and catch the
    error that occurs when the assumptions dont' prove correct
    for example:
    (setq lastObject (vlax-ename->vla-object (entlast)));
    (if
    (null
    (vl-catch-all-error-p
    (setq testvalue
    (vl-catch-all-apply
    'vlax-get-property
    (list lastobject 'centroid)
    );catch
    );setq
    );err
    );null
    (progn
    (print"Value obtained: ")(princ testvalue)
    )
    (print"Error occurred trying to get property")
    )

    then you can go back and figure out why what you thought had happened, in
    fact hadn't

    Probably what Jeff caught is the problem in this case

    hopefully these ideas can help save you some time in the future
    hth
    Mark
     
    Mark Propst, Jan 31, 2004
    #12
  13. Kiwi Russ

    Doug Broad Guest

    Kiwi,

    The best way to debug programs like this is to use vlide and
    load one line at a time. As each line executes, you can see what
    is going on.

    You make a rectangle and capture it as E6. Then you copy
    it (which makes a new last entity). Then you extrude the
    first entity(not the last entity), which now becomes a 3dsolid.
    When you then ask for the last entity, it is not the solid but the
    copy of the first rectangle (a polyline) which has no centroid
    property. The extrude command does not create a new entity.
    It instead changes the object type of the original rectangle.

    Does that help?

    The task could be done a lot easier though ;-)
     
    Doug Broad, Jan 31, 2004
    #13
  14. Kiwi Russ

    Doug Broad Guest

    And the polyline won't extrude anyway unless you close it.
     
    Doug Broad, Jan 31, 2004
    #14
  15. Kiwi Russ

    Doug Broad Guest

    Sorry Kiwi,
    Was wrong about the last entity. If the extrude command works, it creates a
    new entity but it won't work unless
    1) the polyline is closed,
    2) the widthst is non nil,
    3) you fix these lines:
    OriCen3 (vlax-safearray->list;convert centroid to list
    (vlax-variant-value;convert centroid to variant
    4)....well I stopped there.
     
    Doug Broad, Jan 31, 2004
    #15
  16. Kiwi Russ

    Jeff Mishler Guest

    Russ,
    Just to follow up a little, Doug mentioned being able to do this alot
    easier, let me explain my thinking....

    First, you make a layer and never put anything on it, then you try to purge
    it when it is still the current layer....... eliminate this altogether.

    Second, here's the same thing you were doing:

    (defun c:NEWcent(/ sf pt1 pt2 pt3 pt4 vname3 cent)
    (setq sf 50
    pt1 '(0 0 0)
    pt2 (polar pt1 0 3000)
    pt3 (polar pt2 (* 0.5 pi) 1000)
    pt4 (polar pt3 (* 1.0 pi) 3000)
    )
    (command "pline" pt1 pt2 pt3 pt4 "c" "")
    (command "region" (entlast) "")

    ****only 2 lines of code are needed right here, if you want to figure it out
    on your own, now's your chance. Otherwise I've put them at the end of this
    message.

    (command "_.INSERT" "TEST" cent sf "" 0);insert centroid mark
    );defun

    HTH a little more,
    Jeff

    *****2 missing lines of code below here......












    *************don't cheat!
















    *************are you sure?



















    OK, here they are:

    (setq vname3 (vlax-ename->vla-object (entlast)))
    (setq cent (vlax-get vname3 "centroid"))
     
    Jeff Mishler, Jan 31, 2004
    #16
  17. Kiwi Russ

    Kiwi Russ Guest

    Thanks guys
    yeah The reason why it wasn't working was because I didn't
    use "close" when I drew my pline. Something simple I had overlooked! It is
    hard to find something like that using vlide debugger .
    many thanks again for your answers
    Russ
     
    Kiwi Russ, Jan 31, 2004
    #17
  18. Kiwi Russ

    ECCAD Guest

    No,
    I was trying to get him to see that the 'Extrude' - at that point, had not produced a 'new' entity - hence, entget would error, and possibly lead him in that direction - guess he didn't get the jist of it. (Just my bad humor I guess). Anyway, he got there (needed to 'close') and release the object. Sigh.

    Bob
     
    ECCAD, Feb 1, 2004
    #18
  19. Kiwi Russ

    Mark Propst Guest

    I'm still not sure i'm following your thoughts yet, since entlast will
    always point to something, entget wouldn't really error would it?
    But I figured since entget would cause vlax-ename to error (list instead
    of ename) that it wouldn't confirm entlast was the wrong object, it would
    just error out. I thought in this case he'd want to check entlast to confirm
    it was the solid he was looking for. But since your contributions are
    consistently of such a high caliber, I assume i'm missing something here.
     
    Mark Propst, Feb 1, 2004
    #19
  20. Kiwi Russ

    ECCAD Guest

    Mark,
    Since the entlast was 'really' just a pline from Pt3 to Pt4 (not a closed pline), extruding it doesn't apply, therefore, not 'creating' a new entity. When (if) he would have attempted to (getent (entlast)), it would return a 'list', error the Object, leave it nil..he would then 'see' the (list), find it contained info on just one pline element, (maybe). Later we find that he needed a "c" to close the pline, making it more interesting to examine.
    I kind of dived into it in the middle, a little late as it would seem.
    Bob
     
    ECCAD, Feb 1, 2004
    #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.