Jump to content

LISP script to perform Ordinate Dimension verification


Matt_D

Recommended Posts

Hi All.

 

This is my second attempt to post this since somehow I was logged out automatically. Thankfully I had most of this saved via a notepad file.

 

Now down to business: I'm good with CAD, but when it comes to LISP, i'm a complete beginner. My boss/manager has asked me to create a LISP routine that will be run with

a command from the command line and will receive user input to compare to ordinate dimensions within the drawing. I've been on this for two days, trying to wrap my head around even the basics and I can tell you my brain hurts. Programming of any sort is not my forte, i'm still struggling with getting HTML down. Anyways, the reason why my boss would like this is because sometimes our drawings have from a dozen to 50 or so ordinate dimensions and it's tedious to go and check them all against a point. My boss has given me free reign on how to design this sucker, but I'm stumped at how to program it as I'm a newbie. Below is what the lisp routine should be able to accomplish.

 

The idea for the LISP is this:

 

1.) Load the lisp up and have it start with a defun C: command.

 

2.) have the user pick an 'origin' point for comparison (because we don't always use 0,0,0).

 

3.) the lisp takes this point and stores it.

 

4.) It scans the drawing for Ordinate Dimensions only.

 

5.) It compares the origin point of the user to the origin point of the ordinate dimensions. (I figure this would be the endpoint closest to 0,0,0. So for instance, if we have 15 dimensions, there are 30 endpoints. The 15 closest endpoints would be the ones that are compared to the origin point of the user.)

 

6.) It creates a new layer called DIM_WRONG [or whatever] and makes the layer RED.

 

7.) It draws attention to the incorrect ordinate dimensions (the ones scanned and compared to the user's origin point) by drawing either a red box around the dimension or a rev cloud. these rev clouds are placed on the DIM_WRONG layer, with the layer set to not plot. This way we can easily check between 15 and 30 and more ordinate dimensions with a few clicks. There would be a tolerance in the comparison, up to 1/64 of an inch tolerance. If the ordering steps needs to be adjusted because of programming structure, so be it, it just needs to compare those ordinate dimensions with a user assigned origin point, entered by keyboard or mouse.

 

Again, I'm a beginner with Lisp and I've been trying to get segments done and have been only able to get 4 of the easy ones done (from that list). I've never been good at programming with anything.

 

Any help would be vastly appreciated and I thank you for any advice/knowledge that you can bestow.

Edited by Matt_D
formatting cleanup
Link to comment
Share on other sites

  • Replies 24
  • Created
  • Last Reply

Top Posters In This Topic

  • Matt_D

    12

  • BIGAL

    6

  • BKT

    5

  • Cad64

    1

Top Posters In This Topic

Posted Images

2 suggestions 1 post your code and 2 use dumpit.lsp to invetsigate the properties of an object or (entget (car (entsel))) and look at the dxf code number stuff.

 

Command: dumpit

Select object: ; IAcadDimOrdinate: AutoCAD Ordinate Dimension Interface
; Property values:

;   Measurement (RO) = 7930.37
;   TextPosition = (7930.37 1603.47 0.0)

(entget (car (entsel))
(10 0.0 0.0 0.0) (11 7930.37 1603.47 0.0) (12 0.0 0.0 0.0)(13 7930.37 2962.13 0.0) (14 7930.37 1604.26 0.0) these may be useful

Link to comment
Share on other sites

My Code below. It's what I've assembled so far and what has 'worked' and not thrown any errors/done what was needed.

 

New layer:

(command "-layer" "m" "DIM_WRONG" "c" "red" 
"DIM_WRONG" "p" "n" "s" "DIM_WRONG" "" "")

Ordinate Check:

(defun c:ordinatecheck () 
(sssetfirst sel1 (ssget "X" '((0 . "DIMENSION")))) 
)

User stored origin

(defun c:ordinateorigin ()
(setq origin (getpoint "Pick a point or type coordinate: "))
)

The beginnings of trying to create a list

(defun c:createlist ()
(setq ss (ssget "X" '((0 . "*DIMENSION"))))
)

The Revcloud attempt:

(defun c:revcloud (/ ss i)
 (if (setq ss (ssget '((0 . "*POLYLINE"))))
   (repeat (setq i (sslength ss))
     (command "_.revcloud" "" (ssname ss (setq i (1- i))) "")
   )
 )
 (princ)
)

Again, I'm as green as they come with lisp and I'm still working on HTML. This area [programming...even SQL is not my forte]

Link to comment
Share on other sites

Revcloud requires a series of points or object, maybe from a testing point of view use circle and use the text position for centre. Assoc 10.

 

Why all the mini defuns ? Yes I use lots of library defuns but these are to unique, just code a master defun so as to localise variables. My take on a library example (revcloud obj) can be any object then rather than hard coded to a pline.

 

(defun c:revcloud ( obj / )
 (command "_.revcloud" "O" obj "")
 (princ)
)

 

using a dim as the object v's using a circle at text position

Command: REVCLOUD

Minimum arc length: 150.0000 Maximum arc length: 150.0000 Style: Normal

Specify start point or [Arc length/Object/Style] : o

Select object: Unable to convert object, must be a polyline, spline, or circle.

Select object: *Cancel*

Link to comment
Share on other sites

Revcloud requires a series of points or object, maybe from a testing point of view use circle and use the text position for centre. Assoc 10.

Yeah, I realized that and found another snippet of lisp online that will serve my purposes better.

 

Why all the mini defuns ? Yes I use lots of library defuns but these are to unique, just code a master defun so as to localise variables.

These were to make sure that what I was working was working and not throwing up errors. As I stated, I'm literally learning this stuff as I'm writing this rather complex lisp routine (it's complex/complicated to me) and these unique defuns are helping me break the code down and make sure the individual segments are working properly. I definitely plan on taking them out when I get all the individual pieces built and put into one.

 

It's going to be a painful process for me. Mostly because this is not my forte and it's extremely difficult for me to grasp these concepts.

Link to comment
Share on other sites

To test one line at a time copy from notepad to command line, the other thing I do is put some princ in the code like (princ "wow1") " wow2" etc then I can see where it stopped. Or use vlide and you can use the last break point to see where your code stopped. You can inspect variable values looking for say NIL which means variable has not been set. Lee-mac has a good tutorail on using the VLIDE.

Link to comment
Share on other sites

I've modified my method in theory a little. Instead of a compare and contrast, I'm thinking about doing an 'if' statement. the brackets '[ ]' are saying that I don't know what syntax to use to make it work, just my thoughts on what i want it to do.

 

I'm going to be doing this without the code bracket so you can see my thoughts.

 

(defun c : ordinatecheck ( )

 

[this segment works in autocad]

(command "-layer" "m" "DIM_WRONG" "c" "red"

"DIM_WRONG" "p" "n" "s" "DIM_WRONG" "" "")

 

[as well as this segment]

(setq origin (getpoint "Pick a point or type

coordinate: "))

 

[from here, I'm nearly clueless with syntax]

 

IF ( [ordinate dimension point '10'] = origin [user input])

(progn ( [do nothing] ) ; I believe i put 'nil' here?

(/= origin) ; this part starts the sequence of what I need done

(setq ss (ssget [select object] '((100 . "AcDbOrdinateDimension")))) ;so it selects the ordinate dimension in the if statement. i think i may have the structure backwards?

( [syntax to make it draw an entity] '(0 . "Line) (100 . "AcDbLine")

(cons 10 LineStPt) (cons 11 (LineEdPt) ; telling it to draw the line end points

( [on ordinate points '10' to '11'] ) ; I used dumpit to figure out the proper end points so that the line would be drawn and represent the proper wrong ordinate dimension

( [foreach] ) ;for each ordinate dimension

)))

 

Let me know what I did wrong, re-write, whatever.

 

 

Edited by Matt_D
added info
Link to comment
Share on other sites

We still don't know how to determine which dimension is right and not to be revclouded and which one is wrong in respect of picked origin... Elaborate...

Link to comment
Share on other sites

2.) have the user pick an 'origin' point for comparison (because we don't always use 0,0,0).

5.) It compares the origin point of the user to the origin point of the ordinate dimensions [which is point '10'] . (I figure this would be the endpoint closest to 0,0,0. So for instance, if we have 15 dimensions, there are 30 endpoints. The 15 closest endpoints would be the ones that are compared to the origin point of the user.)
If the user point origin is = to ordinate dimension point 10, then it skips it. If it's NOT equal, it draws a red line on the ordinate dimension, from point 10 to point 11 which is at the text of the ordinate point.

 

Basically, what I'm saying is that the user picked origin point is the Correct origin point and if another ordinate dimension [point 10] falls on it, that ordinate dimension is deemed 'correct' and it skips it. If the ordinate dimension [point 10] does not fall on the user origin point, it draws the line indicating it's wrong.

 

Here is the code that I've generated:

 

(defun c: ordinatecheck
 ()
 (setq origin (getpoint "Pick a point or type
coordinate: "))

 (command "-layer"  "m" "DIM_WRONG" "c" "red" "DIM_WRONG" "p" "n" "s" "DIM_WRONG" "" "")
 (if T
   ((10 . *) (100 . "AcDbOrdinateDimension") = !origin)
   (progn (nil))
   (/= origin)
   (setq ss (ssget "X" '((100 . "AcDbOrdinateDimension"))))
   (setq StPt (cdr (assoc 10)))
   (setq EdPt (cdr (assoc 11)))
   (entmake
     (list
   '(0 . "LINE")
   '(100 . "AcDbLine")
   (cons 10 LineStPt)
   (cons 11 LineEdPt)
   (foreach)
     )
     (princ)
   )
 )
 defun
)

I put it into Visual Lisp and that's the format that came out. Getting a 'bad defund syntax' error.

Edited by Matt_D
Link to comment
Share on other sites

A rehack

(if (setq ss (ssget "X" (list (cons 0 "DIMENSION")(cons 100 "AcDbOrdinateDimension"))))
(progn
(repeat (setq x (sslength ss))    
(setq obj (entget (ssname ss (setq x (- x 1)))))
(setq StPt (cdr (assoc 10 obj)))
(setq EdPt (cdr (assoc 11 obj)))
(alert (strcat "x="(rtos (car edpt) 2 2) "y="(rtos (cadr edpt) 2 2))) 
(if (= origin stpt)
(progn
do something here
)
)
)

)

Edited by BIGAL
Link to comment
Share on other sites

I don't read code very well. Where does this go? I'm assuming that it should go were my 'setq' is?

 

EDIT: attempted to use it and got this

 

; error: malformed list on input

I'm lousy at code and worse at debugging.

 

EDIT #2:

After a little format tweaking and missing parenthesizes from above, then a Defun error, this is the following that's come up with a "too many arguments" error.

 

(defun c:ordinatecheck
 ()
 (setq origin (getpoint "Pick a point or type coordinate: "))

 (command "-layer" "m"    "DIM_WRONG" "c" "red" "DIM_WRONG" "p" "n" "s" "DIM_WRONG" "" "")
 (if T
   ((10 . *) (100 . "AcDbOrdinateDimension") = !origin)
   (progn (nil))
   (/= origin)
   (setq ss (ssget "X" (list (cons 0 "DIMENSION")(cons 100 "AcDbOrdinateDimension"))))
   (repeat (setq x (sslength ss))<---
       (setq obj (entget (ssname ss (setq x (- x 1)))))
       (setq StPt (cdr (assoc 10 obj)))
       (setq EdPt (cdr (assoc 11 obj)))
       (alert (strcat "x="(rtos (car edpt) 2 2) "y="(rtos (cadr edpt) 2 2))) 
       (if (= origin stpt)<---
           (progn
           (entmake
             (list
           '(0 . "LINE")
           '(100 . "AcDbLine")
           (cons 10 LineStPt)
           (cons 11 LineEdPt)
           (foreach)
)
)
)
)
)
)
)

Edited by Matt_D
Link to comment
Share on other sites

Did you look at my code there are lots of errors in your code.

 

(if [color=red]T[/color]
[color=red]((10 . *) (100 . "AcDbOrdinateDimension") = !origin)[/color]
(progn[color=red] (nil))[/color]
[color=red](/= origin)[/color]
(setq ss (ssget "X" (list (cons 0 "DIMENSION")(cons 100 "AcDbOrdinateDimension"))))
(repeat (setq x (sslength ss))[color=red]<---[/color]
[color=#ff0000][color=red]

[/color]

[/color]

Link to comment
Share on other sites

Did you look at my code there are lots of errors in your code.

 

(if [color=red]T[/color]
[color=red]((10 . *) (100 . "AcDbOrdinateDimension") = !origin)[/color]
(progn[color=red] (nil))[/color]
[color=red](/= origin)[/color]
(setq ss (ssget "X" (list (cons 0 "DIMENSION")(cons 100 "AcDbOrdinateDimension"))))
(repeat (setq x (sslength ss))[color=red]<---[/color]

 

No offense, but according to AutoCAD, yours wouldn't even run. malfunction error, defun error, missing paranthesis error. You name it, autocad threw it.

 

In your coding, autocad stops here every single time with a syntax error.

(if [color=red]T[/color][color=red]
((10 . *)[color=black]

I can't it past this part and I'm googling to figure a way around it.

[/color]

I know that there are lots of errors in my code. The whole structure probably should be re-written, but I've said it multiple times already and yet it's ignored. I don't know coding and self teaching something that is not my forte is extremely difficult. I had difficulty when trying to learn SQL from a teacher who know it with 10 years of experience.

[/color]

Link to comment
Share on other sites

Matt_D,

 

I think BIGAL was just giving you examples of things you could/should change, not finished code, so I wouldn't expect it to run without modifications.

 

I went through the code and commented out some lines just to get it running so I could see how it might work, and made a couple of changes and notes. (You'll need to close out the alert window after each check, but you could comment that out if you wanted to.)

 

(defun c:ordinatecheck
 (/ origin ss obj StPt EdPt x)
 (setq origin (getpoint "Pick a point or type coordinate: "))

 (command "-layer" "m" "DIM_WRONG" "c" "red" "DIM_WRONG" "p" "n" "s" "DIM_WRONG" "")
;  (if T
;    ((10 . *) (100 . "AcDbOrdinateDimension") = !origin)
;    (progn (nil))
;    (/= origin)
;    (setq ss (ssget "X" (list (cons 0 "DIMENSION")(cons 100 "AcDbOrdinateDimension"))))
   (if (setq ss (ssget "X" (list (cons 0 "DIMENSION")(cons 100 "AcDbOrdinateDimension"))))
   (repeat (setq x (sslength ss))<---
       (setq obj (entget (ssname ss (setq x (- x 1)))))
       (setq StPt (cdr (assoc 10 obj)))
       (setq EdPt (cdr (assoc 11 obj)))
       (alert (strcat "x="(rtos (car StPt) 2 2) " y="(rtos (cadr StPt) 2 2))) [color=red];; Changed to StPt?[/color]
       (if (equal origin StPt)<--- [color=red];; Changed "=" to "equal"[/color]
;            (progn
           (entmake
             (list
           '(0 . "LINE")
           '(100 . "AcDbLine")
           (cons 10 StPt) [color=red];; Changed to StPt[/color]
           (cons 11 EdPt) [color=red];; Changed to EdPt[/color]
;            (foreach)
)
)

)

)
)
(princ)
)

Link to comment
Share on other sites

I think BIGAL was just giving you examples of things you could/should change, not finished code, so I wouldn't expect it to run without modifications.
I'm lousy at code and worse at debugging.
I feel like a broken record. I'm not good with programming of any sort, so any 'suggestions' aren't going to make sense to me. I need finished code to work and pick through to change and have it do what I wish to.

 

And as for the code you presented, it's definitely a start in the right direction. I just need to modify it to only draw lines on the ordinate dimensions whose ordinate point doesn't like up with the user input origin. So I thank you for helping there. I'll be looking through my coding and analyzing yours to figure the difference out and understand it. once I get it drawing lines on only what I want it to draw lines on, I'll be posting the code back up.

Edited by Matt_D
Link to comment
Share on other sites

I think you'll find that, at CADTutor, most times you won't get folks to post finished code right away. The idea is to attempt to help with the learning process.

 

That being said, does the code now draw a line to the "shifted" dimensions?

Link to comment
Share on other sites

This is close and should guide you, still a bit confused about which points to compare

 

(command "-layer"  "m" "DIM_WRONG" "c" "red" "DIM_WRONG" "s" "DIM_WRONG" "")
(setq origin (getpoint "Pick a point or type coordinate: "))
(if (/= (setq ss (ssget "X" (list (cons 0 "DIMENSION")(cons 100 "AcDbOrdinateDimension")))) NIL)
(progn
(repeat (setq x (sslength ss))    
(setq obj (entget (ssname ss (setq x (- x 1)))))
(setq StPt (cdr (assoc 10 obj)))
(setq EdPt (cdr (assoc 11 obj)))

(if (= origin stpt)
(progn
(entmake (list
   (CONS 0  "cIRCLE")
   (cons 10 EDPt)
   (cons 40 10)
)
) ; entmake
) ;PROGN
) ; IF
) ; PROGN
) ; IF
(PRINC)

Link to comment
Share on other sites

This is close and should guide you, still a bit confused about which points to compare

With all due respect, I explained this in clear English, unless English is your second language, of which I shall explain it again.

 

The purpose of this lisp is to compare a User given point or datum to the ordinate dimension datum. So for instance, lets say that the correct datum is 0,0,0. And through drawing editing, the ordinate dimensions that are on the drawing somehow get moved from 0,0,0. Say one gets moved to 1,0,1 and another is moved to 1,1,0. The lisp routine will scan all the ordinate dimensions and compare their datums to the user given datum of 0,0,0. Those two ordinate dimension datum that are 1,0,1 and 1,1,0 will be flagged and the lisp will draw a line from their points, indicating that they are incorrect while ignoring other ordinate dimension datums that are 0,0,0.

 

I think you'll find that, at CADTutor, most times you won't get folks to post finished code right away. The idea is to attempt to help with the learning process.
Yeah, I don't learn code well outside a classroom. I'm one who needs finished code to learn how to construct new code.

 

Bigal:

Now I'm going to get back to the lisp routine that was posted. I tried to follow your code, but I don't understand why you nullified the first IF statement.

 

I've tried to switch the IF statement from BKT to saying NOT EQUAL, but the lisp keeps throwing an error.

(defun c:ordinatecheck2
 (/ origin ss obj StPt EdPt x)
 (setq origin (getpoint "Pick a point or type coordinate: "))

 (command "-layer" "m" "DIM_WRONG" "c" "red" "DIM_WRONG" "p" "n" "DIM_WRONG" "s" "DIM_WRONG" "")
;  (if T
;    ((10 . *) (100 . "AcDbOrdinateDimension") = !origin)
;    (progn (nil))
;    (/= origin)
;    (setq ss (ssget "X" (list (cons 0 "DIMENSION")(cons 100 "AcDbOrdinateDimension"))))
   (if (setq ss (ssget "X" (list (cons 0 "DIMENSION")(cons 100 "AcDbOrdinateDimension"))))
   (repeat (setq x (sslength ss))
       (setq obj (entget (ssname ss (setq x (- x 1)))))
       (setq StPt (cdr (assoc 10 obj)))
       (setq EdPt (cdr (assoc 11 obj)))
;        (alert (strcat "x="(rtos (car StPt) 2 2) " y="(rtos (cadr StPt) 2 2))) ;; Changed to StPt?
       (if ([b][color=red]not[/color][/b] equal origin StPt) ;; Changed "=" to "equal"
;            (progn
           (entmake
             (list
           '(0 . "LINE")
           '(100 . "AcDbLine")
           (cons 10 StPt) ;; Changed to StPt
           (cons 11 EdPt) ;; Changed to EdPt
;            (foreach)
)
)

)

)
)
(princ)
)

A 'too many arguments' crops up. Otherwise the lisp draws lines on every ordinate dimension in the drawing. I'm trying to drop this down to either one of two things:

 

Drawing the line on WRONG ordinate dimensions and coloring the line RED to indicate as such. Then the user can correct those that are wrong.

 

OR

 

Drawing the line on CORRECT ordinate dimensions and coloring the line GREEN to indicate as such. Then the user can ignore those that are right and fix those that are wrong.

 

Please use the code I posted with the red NOT. The other has problems with the layer part.

Link to comment
Share on other sites

You didn't answer my question concerning whether not the code I provided drew lines from the displaced datum to the dimensions. It does for me and that's why I asked.

 

With regard to your question about switching to NOT EQUAL, you need to separate the NOT from the EQUAL with another set of "()":

 

(if ([b][color=red]not[/color][/b] [color=red]([/color]equal origin StPt)[color=red])[/color] ;; Changed "=" to "equal"

Link to comment
Share on other sites

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...