How accurate is AutoCad then?

Discussion in 'AutoCAD' started by Roderic Potter, Jan 28, 2004.

  1. With the help of some brilliant members of this newsgroup I have managed to
    write some code that allows me to automatically ascertain the layer of an
    existing entity just by picking somewhere on it.

    Example:
    I have a line representing a pipe, and the line resides on layer H-SM-PIP-P,
    for "mechanical schematic piping planned" (Canadian PWGSC layer standard).
    I want to insert a block on this line to represent an "elbow" in the pipe,
    and I want this block to automatically jump to the related H-SM-PIP-FTG-P
    layer, for "fittings".

    I normally used to make sure the piping layer was current, then insert the
    block, and my existing code flipped the block to the right layer after
    insertion.

    My new code now allows me to do all of this automatically without having to
    set the particular layer current first, because when I osnap onto the line,
    the pick function reveals what layer the pipe line is on, thus revealing to
    the code what the associated layer is.

    This works brilliantly under normal circumstances, UNTIL I am not zoomed in
    far enough.

    If I try this from too far out (zoom-wise), and osnap endpoint onto the
    line, AutoCad does not find the line - in fact it finds NOTHING and thinks
    the layer of the entity is layer ZERO.

    This is not cricket as they say.

    Is there a setting somewhere in AutoCad that will alter its ability to look
    deep inside a pick?

    regards
     
    Roderic Potter, Jan 28, 2004
    #1
  2. Roderic Potter

    R.K. McSwain Guest

    R.K. McSwain, Jan 28, 2004
    #2
  3. Roderic Potter, Jan 28, 2004
    #3
  4. Roderic Potter

    Rudy Tovar Guest

    Try setting a filter to only gather endpoint of a given line.

    Besides, your command alone commits to what will the utility will be set to.

    In either case, you can also apply conditions
    (cond
    ((= <val> <setting>)(Do_this))
    ((= <val> <setting>)(Do_that))
    )

    (setq ent (ssget (list (cons 8 <layer>))))

    Under an circumstances you can define an infinite amount of conditions
    solutions.

    You can even have it do it for you automatically.

    (setq ob (ssget (list (cons 8 <layer,layer,layer,etc>))))

    Foreach endpoint of given line on layer, check assoc 10 and 11 for block
    insertion and given point, if not insert block, trim as required. Complete
    Automation can be accieved by each step you predefine. Even drawing the
    lines can be set to automatically insert a given block and the right elbow.

    To break and insert a connection can be predefined by assuming that you have
    a clear understanding of given posibilities, distance, location, angle,
    type.
    --

    AUTODESK
    Authorized Developer
    www.Cadentity.com
    MASi
     
    Rudy Tovar, Jan 28, 2004
    #4
  5. Excellent advice Rudy
    many thanks

     
    Roderic Potter, Jan 28, 2004
    #5
  6. Roderic Potter

    ECCAD Guest

    What function are you using to 'get' the picked object. ?
    (entget (...
    or
    (vlx-get...
    In either case, you could examine the 'returned' entity.
    Like so:
    (setq obj nil)
    (setq obj (entsel..)
    (if obj
    (progn
    ..do your thing
    ))
    ------
    (if (= obj nil)
    (prompt "\nZoom in a bit..nothing selected..")
    );eif

    Bob
     
    ECCAD, Jan 28, 2004
    #6
  7. Hi Bob

    Following is a sample bit of my code:

    (setq pt1 (getvar "lastpoint"))
    (setq ee1 (nentselp pt1))
    (setq ee (car ee1))
    (if ee
    (progn
    (setq e (entget ee))
    (setq n (cdr (assoc 8 e)))
    (command "LAYER" "SET" n "")
    ))

    As you can see, I am using the "nentselp" statement for getting the object.
     
    Roderic Potter, Jan 28, 2004
    #7
  8. Roderic Potter

    R.K. McSwain Guest

    Sorry, I was just answering the subject of your post :)
     
    R.K. McSwain, Jan 28, 2004
    #8
  9. Roderic Potter

    ECCAD Guest

    Hi Roderic,
    All I'm saying here (based on your post of the problem)...
    You may want to nil out the ee variable - somewhere in the loop, so next time in, it is nil to begin with. If you don't set it to nil, may be set to (last run) value, and execute.
    So:
    (setq ee nil)
    (setq pt1 (getvar "lastpoint"))
    ...
    IF ee
    do the work
    IF NOT ee
    (zoom out a little)
    ..
    You could also set in while loop, waiting for ee to be set.
    E.G.
    (setq ee nil)
    (while (= ee nil)
    (progn
    ..... do your thing
    )
    (if (= ee nil)
    (prompt "\nZoom out a little..")
    )
    ); e while
     
    ECCAD, Jan 28, 2004
    #9
  10. Excellent response from the group, as normal
    I owe you a beer!

    time in, it is nil to begin with. If you don't set it to nil, may be set to
    (last run) value, and execute.
     
    Roderic Potter, Jan 28, 2004
    #10
  11. Roderic Potter

    John Uhden Guest

    Really don't mean to bust you; just rattling your brain a little.

    If you're picking the object, why don't you use (nentsel) instead of (nentselp)?
    Depending on your zoom level and the proximity of other objects, (nentselp) can
    be hit or miss or hit the wrong target.

    Anyway, (nentselx) will return nested entities as well, so if you pick an entity
    within an xref, you can't possibly set its externally referenced layer current,
    so you ought to use (entsel) instead. Then again, you should have available
    what AutoCAD already provides... ai_molc.
     
    John Uhden, Jan 29, 2004
    #11
  12. Not having a thorough knowledge of Lisp and the various commands that are
    available, I was not aware that I could simply use (nestsel) instead. I
    muddle through normally and was pointed towards (nentselp) by another kind
    person in this newsgroup.

    Thanks, I will try it out.

    I find it interesting that no-one has commented on the REAL problem here,
    that is, the accuracy of AutoCad. If I osnap onto the endpoint of a line,
    even when I am zoomed a LONG way out, AutoCad should find the line, not
    nothing. No-one has commented on this...

    best regards
     
    Roderic Potter, Jan 29, 2004
    #12
  13. Roderic Potter

    Jeff Mishler Guest

    Actually, a few of the posts pointed you in the right direction to answer
    this question. The biggest problem I see is that we/you have no way of
    knowing what "lastpoint" was and what entity it may, or may not, be near.

    First, how do you know "it finds nothing"? As John pointed out, if it finds
    a nested entity in an xref the layer can't be made current which will cause
    an error.

    With (entsel) you are picking the object and when the pickbox is a certain
    size larger than 0 it is relatively easy to pick the object you intend. Now,
    change the pickbox smaller, 1 size at a time, until you get to 0, trying to
    pick the same entity at each stage. It gets tougher, doesn't it?

    Now with (nentsel) you are passing it a specific point, without the benefit
    of a pickbox, and expect it to find an entity from far away. Now IF the
    point is EXACTLY on the intended object, it should find it, but if it falls
    to the side, even by a small amount, it probably won't.

    Hence John's suggestion of using (entsel), you are ensured of getting a
    valid object.

    Just some thoughts,
    Jeff
     
    Jeff Mishler, Jan 29, 2004
    #13
  14. Roderic Potter

    John Uhden Guest

    Thanks, Jeff. You said it better than I could. :)

    Meanwhile, doesn't everyone have a little icon for "Make object's layer
    current"?
     
    John Uhden, Jan 30, 2004
    #14
  15. I would like to add to Jeff's comments.

    1. In your first post on 1/23/04, you wanted to use running osnaps in
    conjunction with entsel. I offered an example of using getpoint and
    nentselp to accomplish this. Someone may be able to prove me wrong on this,
    but I have never been able to make this method fail.

    2. In your second post on 1/23/04, you wanted to know of a way to obtain
    the point at which the user just inserted a block for later use in obtaining
    the layer in which the block was inserted on.

    Now you are trying to use nentselp to obtain the layer of the object that
    the block was inserted on. If the insertion point of the block is touching
    an entity in the block then your chances are good that nentselp will grab
    the insert instead of the entity that you inserted the block on to. Hope
    this makes sense.

    I guess my point is that if you ask for solutions to specific tasks that is
    what you are going to get. You are going to get a way to use osnaps and
    entsel. You are going to get a way to obtain the last point picked by a
    user. But this doesn't mean that these specific task are the correct
    direction to head in accomplishing your overall goal. Your question has
    been answered in this thread just as they were in the previous two, but it
    looks to me that you are no closer to completion. Try posting your overall
    goal and code and I bet you get all the answers you need or at the very
    least a good head start and direction.

    Ken Alexander
     
    Ken Alexander, Jan 30, 2004
    #15
  16. You guys are really great taking such an interest in this, thanks!

    Jeff asked the question "how do you know that AutoCad finds nothing?" - well
    I assume this because if I am zoomed a long way out and I use the code to
    osnap onto the endpoint of a line, the layer that is made current is layer
    ZERO, not the layer of the line itself.

    Now to give you a bit of background, as I explained in an earlier post, I
    draw mechanical building systems, including pipes.

    On a typical floor plan or maybe schematic, I will have a bunch of lines
    quite near to each other representing many different pipes such as domestic
    cold water, natural gas, steam, you name it.

    Typically all of these pipes will run along together and all bend through
    90deg at the same spot, because we are neat people and that's the way we do
    things.

    After drawing all of these "bends", I have to add the "elbow" blocks which
    are simply blocks that represent the "joints" at the elbows. These blocks
    have to flip onto associated layers, and I wrote the code to make that
    happen automatically some time ago, but for this to work, I have to be on
    the correct pipeline layer (for each pipe) before I insert the elbow block.

    This requires me to use the "set entity layer current" icon as mentioned by
    John, before each block insertion, otherwise the elbow for the cold water
    pipe will flip onto the layer associated with natural gas (hypothetically).

    (bored yet?)

    Anyway assuming I have a bunch of these insertions to do, it occurred to me
    that having to pick/make layer current each time prior to block insertion
    was tedious at best, and I have tried to make this all happen automatically
    by virtue of picking on the entity itself. Therefore I could be sitting on
    layer zero, and proceed to insert all of these blocks one after the other,
    never having to worry about being on a pipeline layer first, because when I
    osnap onto the endpoint of each line, it determines the layer of the line,
    makes that layer current, and flips the block insertion onto the associated
    layer.

    (phew)

    I trust that this explains what I am trying to achieve.

    Now getting back to a previous bit of code I posted:

    (COMMAND "insert" blank PAUSE 1.0 "" 0)

    (setq pt1 (getvar "lastpoint"))
    (setq ee1 (nentselp pt1))
    (setq ee (car ee1))
    (if ee
    (progn
    (setq e (entget ee))
    (setq n (cdr (assoc 8 e)))
    (command "LAYER" "SET" n "")
    ))

    (do insertion stuff)....

    This is where I am. The original insert command determines the point at
    which I want the insertion to take place, and the "blank" is merely a
    preview block that helps me see the size of the block before insertion.

    I will experiment with using (nentsel) instead of (nentselp).

    best regards
     
    Roderic Potter, Jan 30, 2004
    #16
  17. Roderic Potter

    Jeff Mishler Guest

    Roderic,
    I now see what, how, & why you are doing things. I would be willing to bet
    that your "elbow" block entities are created on Layer 0, so as to take the
    on the properties of the layer inserted on. Now, when using (nentselp pt) it
    will return the entity it finds at that point, whether it is a line inside
    the elbow block, the line you intended, or something else, all depends on
    how many things are in the same area, your "sort order" for object
    selection, etc. Which means that, based on your reply, (nentselp pt) IS
    finding something, and that something is in the elbow block and is on layer
    0, otherwise your routine wouldn't complete........(try using (entget) on a
    var that is set to nil)

    As for a solution? I would suggest that, since you seem to have a number of
    these elbows to insert in any one area, do something like this (someone else
    may have a better idea, this is just the first thing I thought of):
    create a filtered selection set (ss) of the lines
    pick a point (pt1) close to the end(s) of the line(s) that you want the
    elbow placed
    pick another pt (pt2) for the rotation angle (setq ang (angle pt1 pt2))
    loop thru the (ss) for each line, insert the elbow at the endpoint of the
    line closest to (pt), with the rotation of (ang) and change the insert's
    layer to match that line.
    Done....

    HTH,
    Jeff
     
    Jeff Mishler, Jan 30, 2004
    #17
  18. Interesting idea in your second paragraph about automating the whole set of
    insertions....

    As far as (nentselp pt) finding something, and that thing being in the elbow
    block itself, this cannot be right, because when the code portion I posetd
    actually runs, the elbow block has NOT yet been inserted. All I have done
    is determined the insertion point of LATER FOLLOWING insertion of the
    elbow...

    Of course a solution to all of this is to simply make sure I am zoomed far
    enough in!

    thanks guys
     
    Roderic Potter, Jan 30, 2004
    #18
  19. See if this get you going. You should select your pipe where you
    want the elbow.
    If no pipe is selected then nothing, if there is then elbow will be
    inserted on the same
    layer as the pipe. You can add to this to do as Jeff suggested.
    Also I would look into
    error handlers. BTW I'm assuming that blank is your elbow???

    (defun C:test (/ o-osmode a ent ee e n o-layer)
    (setq o-osmode (getvar "osmode"))
    (setvar "osmode" 512)
    (setq a (getpoint "\nSelect Insert Point: "))
    (setq ss (ssget "c" a a))
    (setvar "osmode" o-osmode)

    (if ss
    (progn
    (setq ee (ssname ss 0)
    e (entget ee)
    n (cdr (assoc 8 e))
    )
    (setq o-layer (getvar "clayer"))
    (setvar "clayer" n)
    (COMMAND "insert" "blank" a 1.0 "" 0)
    (setvar "clayer" o-layer)
    )
    (princ "\nPipe not selected. ")
    )
    (princ)
    )
    --
    Ken Alexander
    Acad2004
    Windows2000 Prof.

    "We can't solve problems by using the same kind
    of thinking we used when we created them."
    --Albert Einstein
     
    Ken Alexander, Jan 30, 2004
    #19
  20. More of my code; as discussed earlier, "blank" is simply a preview block for
    help on-screen when choosing the insertion point; this preview block is
    sized to apply to a multitude of my blocks that I insert using this same
    method, not just elbows...

    (PROMPT "\nPick insertion point <Cancel to exit>... ")
    (COMMAND "insert" blank PAUSE 1.0 "" 0)
    (setq pt1 (getvar "lastpoint"))
    (setq ee1 (nentselp pt1))
    (setq ee (car ee1))
    (if ee
    (progn
    (setq e (entget ee))
    (setq n (cdr (assoc 8 e)))
    (command "LAYER" "SET" n "")
    ))
    (SETVAR "osmode" save_osmode)
    (COMMAND "erase" "l" "");erase the blank after learning the insertion
    point

    ....
    ....insert the elbow or other block now...

    (fittingname
    (COMMAND "insert"
    (STRCAT rootdir fitting)
    "@"
    skale
    ""
    pause
    )
    (c:chgtofittinglayer); flip to the fitting layer

    I see in your code Ken that you save the current layer name and reset it
    back after the routine; I eventually would have added that too.

    best regards
     
    Roderic Potter, Jan 30, 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.