Jump to content

Recommended Posts

Posted

i have a script that draws a series of boxes using the basic structure

(setq pt1 (getpoint "\nClick the location of the top-left corner"))
(setq pt2 (list (+ width (car pt1)) (cadr pt1) 0.0))
(setq pt3 (list (+ width (car pt1)) (- (cadr pt1) height) 0.0))
(setq pt4 (list (car pt1) (- (cadr pt1) height) 0.0))
(command ".pline" pt1 pt2 pt3 pt4 "Close")

with subsequent boxes being based on the location of that start point, i've been having the points print to the command window as u can see in the attached screen shot and they are always correct. Basically the screen shot is of the same function run twice and in one it operates as expected and has 4 boxes with spacing between them, in the other it for some reason increases the size of some of the boxes and makes them all connect, its driving me nuts because its the EXACT SAME FUNCTION just executed at two different coordinates. Any ideas?

 

i've already tried

(command "line" pt1 pt2 pt3 pt4 "Close")
(command "line" pt1 pt2 pt3 pt4 pt1 "Close")
(command "line" pt1 pt2 pt3 pt4 pt1 "Cancel")

plus the mtext labels are based off the top left corner and they always appear in the right spots, so i'm 99.9% sure its not a problem with the numbers i'm feeding it

acad_oddity.jpg

Posted

The OSNAP is causing the trouble. You will either need to use a VL method, or entmake method to create your LWPolyline, or add some code to turn off the OSNAPS.

 

For the VL method, I believe I responded in your other thread:

 


(defun mk_poly (lst)
 (vla-addLightWeightPolyline
   (vla-get-ModelSpace
     (vla-get-ActiveDocument
       (vlax-get-acad-object)))
     (vlax-make-variant
       (vlax-safearray-fill
         (vlax-make-safearray
           vlax-vbdouble (cons 0 (1- (length lst)))) lst)))))

;; (mk_poly '((1 2) (3 4) (5 6)))

For the entmake method, you will need to construct a DXF data list, the reference for which can be found here:

http://autodesk.com/techpubs/autocad/acad2000/dxf/

 

An example of this method:

 

(defun c:pidarrow  (/ Entx elst ent ptlst ang op)
 (vl-load-com)
 (while
   (progn
     (if (setq Entx (entsel "\nSelect Line or 2 Vertice Pline: "))
       (cond ((eq "LINE" (cdadr (setq elst (entget (setq ent (car Entx))))))
              (setq ptlst (list (cdr (assoc 10 elst)) (cdr (assoc 11 elst)))) nil)
             ((eq "LWPOLYLINE" (cdadr (setq elst (entget ent))))
              (if (> (length (setq ptlst
                               (mapcar 'cdr (vl-remove-if-not
                                              '(lambda (x) (= 10 (car x))) elst)))) 2)
                (princ "\n** Polyline has more than 2 Vertices **") nil))
             (t (princ "** Invalid Object Selected **")))
       (princ "\n** Nothing Selected **"))))
 (setq ptlst (vl-sort ptlst
               '(lambda (x1 x2) (< (distance (cadr Entx) x1) (distance (cadr Entx) x2))))
       ang (apply 'angle ptlst))
 (initget "Yes No")
 (setq op (cond ((getkword "\nDouble Arrow Head? [Y/N] <Yes> : ")) ("Yes")))
 (entmakex
   (append
     (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") 
           (cons 90 4) (cons 70 0) (cons 10 (cadr ptlst)) (cons 40 0.) (cons 41 0.))
     (if (= op "Yes")
       (list (cons 10 (polar (car ptlst) ang 16.0)) (cons 40 2.) (cons 41 0.)))
     (list (cons 10 (polar (car ptlst) ang 8.)) (cons 40 2.) (cons 41 0.)
           (cons 10 (car ptlst)) (cons 40 0.)  (cons 41 0.))))
 (entdel ent)
 (princ))

Or, to mess with the OSNAPs:

 

Collect the original setting:

 

(setq oldOS (getvar "OSMODE"))

Turn them off

 

Either:

 

(setvar "OSMODE" 0)

or

 

(and (< 0 (getvar "OSMODE") 16384)
    (setvar "OSMODE" (+ 16384 (getvar "OSMODE"))))

Then make sure you return them to the original setting once finished:

 

(setvar "OSMODE" oldOS)

You may also need to make an error handler for the routine to allow for if the user hits Esc or Ctrl+C.

 

Hope this helps, but if you have any further questions, just ask.

 

Lee

Posted

as always, excellent work lee, i used the "osmode" var change as it was the simplest and it works like a charm :) :) :) so much headache gone :) lol

Posted

Like Lee said when changing system variables it is always good to have an error handling function to set back your osmode. A quick example may look like this

 

(defun *error* (msg)
 (setvar osmode oldOS)
 (princ msg)(princ)
 )

Posted

hmm, would it be possible to have the error statement return a different value? Bit off topic but it'd be nice if i could rig up a function that would auto-correct little errors, like say u ran

(+ 5 "5")

and have it hit an error handler that would determine the data type of the wrong data and use an appropriate function to fix it, in this example it would recognize "5" as a string and realize that its expecting an int so it would do (atoi "5") and use the new value instead

Posted

You should use conditionals within your code instead - once inside the error handler you are at the point of no return... :P

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...