Hello,
I have used another lisp to create a simple lisp for 2d elevation drafting. I need assistance. See below and attached lsip file.
Thank you in advance for any assistance received.
Solved! Go to Solution.
Solved by komondormrex. Go to Solution.
It's not clear to me whether "how it needs to work" is how you think it should be working as written but it isn't, or is "how it works now" correct as written, and you are looking for a modification to make it "how it needs to work." If it's the former, without studying it too deeply, could it be simply that Object snap is on too long? Does it fix it if you move the turning off of running Osnap:
(setvar "osmode" 0)
to earlier, somewhere before the first Line command?
But I suspect it's the latter, since I don't see any 1.5 value as I would expect in the code anywhere.
EDIT: I can't test it, because you did not include a definition of the (working) function. There are some other things that seem peculiar to me, but later....
It is in the creation of the 1st and last points. The draw points need to be 1.5" from the actual picked points. Not sure how to this?
[Still no definition of (working).]
Are the white parts in the image a Polyline? Or separate Lines? It would be far easier to Offset the Polyline [see @john.uhden's link], or to Join the Lines into a Polyline and then Offset it, than to go through all the complications you have. Adjusting the ends of the Offset result, and drawing from them to the original Polyline, should not be difficult.
An example of part of it that seems peculiar to me:
(setq xw (getdist "\nDepth of exposed slab edge <4\">: "))
(if (= xw nil)(setq xw 4.0))
; SO 'xw' WILL ALWAYS BE EITHER THE USER INPUT OR 4.0, WHICH MEANS:
(if
(or (= xw nil) (= xw "")); NEITHER OF THESE WILL EVER BE THE CASE [the 2nd one can't be anyway]
(eval nil); then ; SO IT WILL NEVER DO THIS [what would the purpose be, anyway?]
(setq w xw); else ; BUT WILL ALWAYS DO THIS
); if
So just do that last line (setq w xw) without the (if) function enclosing it.
The white parts could be lines or polylines usually lines. They are not part of the lisp.
I am not a programmer, I tried to use an existing program to develop what I need. I apologize, I mean no disrespect to you guru's.
I'm open yo just about anything. I repeat this same task on exterior elevations time and time again. I'm looking to save myself some time.
@DC-MWA ,
It would be easier if the white surface lines were drawn as one polyline (prior to the program, not during). Then the question is do you want to create the bottom line as a downward copy of the surface or as a downward offset from the surface? Referring to the collection of polylines as a cross section, the answer would be to copy them/it down to represent the depth.
Also, as we civils do, do you want to use a vertical scale factor (usually 10 x horizontal) to make the section more visually clear? After all, a 20' wide slab at 1/3' depth would appear to be the side view of regular cardboard without the vertical exaggeration.
I presume that you would want the bottom and sides to be on a different layer (please provide the name).
Do you want to hatch the enclosed area between the surface and the bottom/sides?
John F. Uhden
@john.uhden wrote:
.....
I presume that you would want the bottom and sides to be on a different layer (please provide the name).
....
Already there.
Hi @DC-MWA
I'm currently at work , will try to decode your current code later today.
Some notes:
(if (= something nil)...)
;replace with
(if (null something)...)
(command ".erase" (entlast) "")
;replace with
(entdel (entlast))
(if (/= f1 nil).....
;replace with
(if f1 ....
;in this case I use
(if (and f1)
Try to replace nested IF commands with COND since it makes code easier to follow
Miljenko Hatlak
hey there,
check this updated
(defun c:screed2 (/ olderr oldlay oldluprec oldfilletrad Curlay layent os xw f1 c f2 w1 w2 e pt1 pt3 pt2 pt4 count end1 enl ss
first_last_offset
)
(defun DTR (a)(* PI (/ a 180.0)));defun ;degrees to radians function
;(GET_VARS)
(setvar "osmode" 1)
(setvar "luprec" 3)
(setvar "FILLETRAD" 0)
(setvar "plinewid" 0)
;;=========================
(command ".-layer" "make" "A-ELEV" "c" "1" "" "")
;;=========================
(if (= w nil) (setq w 1))
(setq f1 nil)
(setq pt4 nil)
(setq f2 nil)
(setq xw nil)
;;---------------
(setq c 0)
;;---------------
(setq xw (getdist "\nDepth of exposed slab edge <4\">: "))
(if (= xw nil)(setq xw 4.0))
(if (or (= xw nil) (= xw "")) (eval nil) (setq w xw))
(setq first_last_offset 1.5)
(Prompt "\nSelect points left to right...")
(setq pt1 (getpoint "\nPick bottom of left side wall: "))
;;draw temporary hokey line
(command ".line" pt1 (polar pt1 (DTR 90.0) 1.0) "")
(setq enl (entlast))
(command ".erase" (entlast) "")
(setq count 1)
(while (setq pt2 (getpoint "\nPick NEXT POINT along wall <return to end>: " pt1 ))
(setvar "osmode" 0)
(working)
(if (/= pt3 nil) (setq f1 pt3))
(if (> c 1) (setq f1 (polar pt3 a W)))
;----------
(setq c (+ c 1))
(setq a (angle pt1 pt2))
(setq pt3 (polar pt1 (- a (dtr 90)) W))
(if (= count 1)
(command "line" (setq pt1 (polar pt1 a first_last_offset)) (setq pt3 (polar pt1 (- a (dtr 90)) w)) "")
)
(setq count (+ count 1))
(setq pt4 (polar pt2 (- a (dtr 90)) W))
(command "line" pt3 pt4 "")
(setq f2 (polar pt2 (- a (dtr 90)) W))
(setq pt1 pt2)
(if (/= f1 nil) (command "._fillet" f1 f2))
(setq end1 pt2)
(setq pt2 nil)
(setvar "osmode" 1)
);while
(setvar "osmode" 0)
(command "line" (setq end1 (polar end1 (- a (dtr 180)) first_last_offset)) (setq pt4 (polar end1 (- a (dtr 90)) w)) "")
(command "._fillet" end1 (polar pt3 a (* 0.5 (distance pt3 pt4))))
;;gather all lines
(setq ss (ssadd))
(while (setq enl (entnext enl))
(ssadd enl ss))
;;join lines
(initcommandversion)
(command "_.join" ss "")
;(RET_VARS)
(Prompt "\nDone!")
(PRINC)
);end defun
@hak_vz wrote:
....
(if (/= f1 nil)..... ;replace with (if f1 .... ;in this case I use (if (and f1)
....
In this case, what purpose is served by putting f1 into an (and) function? Yes, the return from line 3 will be either what's in f1 or nil, while the return from line 5 will be either T or nil. But all the (if) function cares about is whether it's nil or anything else, so it can't make any difference to the outcome.
@DC-MWA ,
I'm a bit tardy here, but I couldn't resist. It has some klunky lines (of code) as it was written for and tested in ACAD2002, but it should work. Please let me know if it doesn't, and how it doesn't.
I'm pretty sure this does what you want. Plus it ignores jagged segments outside the 1.5 unit zone.
(defun c:screed3 ( / *error* vars vals e1 obj1 e2 obj2 e3 obj3
e4 obj4 ent p1 p2 p3 p4 d)
(gc)
(vl-load-com)
(princ "SCREED3 v1.0 (c)2024, John F. Uhden for @DC-MWA.\n")
(defun *error* (err)
(mapcar 'setvar vars vals)
(vla-endundomark *doc*)
(cond
((not err))
((wcmatch (strcase err) "*CANCEL*,*QUIT*"))
(1 (princ (strcat "\nERROR: " err)))
)
(princ)
)
(or *acad* (setq *acad* (vlax-get-acad-object)))
(or *doc* (setq *doc* (vla-get-ActiveDocument *acad*)))
(vla-endundomark *doc*)
(vla-startundomark *doc*)
(setq vars '("cmdecho" "osmode"))
(setq vals (mapcar 'getvar vars))
(mapcar 'setvar vars '(0 0))
(command "_.expert" (getvar "expert")) ;; dummy command
(and ;; The Stephan Koster approach
(setq e1 (car (entsel "\nSelect surface LWpolyline: ")))
(setq obj1 (vlax-ename->vla-object e1))
(setq p1 (vlax-curve-getstartpoint obj1))
(setq p3 (vlax-curve-getendpoint obj1))
(or
(> (abs (apply '- (mapcar 'car (list p1 p3)))) 3)
(prompt "\nObject is not wide enough.")
)
(not (initget 6))
(or (setq d (getdist "\nDepth to bottom <4.0>: "))
(setq d 4.0)
)
(setq obj2 (vla-copy obj1))
(setq e2 (vlax-vla-object->ename obj2))
(or (vla-move obj2 (vlax-3d-point '(0 0 0))(vlax-3d-point (list 0 (- d) 0))) 1)
(setq p2 (mapcar '- p1 (list 0 d 0)))
(setq e3 (entmakex (list '(0 . "LINE")(cons 10 p1)(cons 11 p2))))
(setq obj3 (vlax-ename->vla-object e3))
(setq p4 (mapcar '- p3 (list 0 d 0)))
(setq e4 (entmakex (list '(0 . "LINE")(cons 10 p3)(cons 11 p4))))
(setq obj4 (vlax-ename->vla-object e4))
(if (> (car p3)(car p1))
(progn
(or (vla-move obj3 (vlax-3d-point '(0 0 0))(vlax-3d-point (list 1.5 0 0))) 1)
(or (vla-move obj4 (vlax-3d-point '(0 0 0))(vlax-3d-point (list -1.5 0 0))) 1)
)
(progn
(or (vla-move obj3 (vlax-3d-point '(0 0 0))(vlax-3d-point (list -1.5 0 0))) 1)
(or (vla-move obj4 (vlax-3d-point '(0 0 0))(vlax-3d-point (list 1.5 0 0))) 1)
)
)
(setq p1new (vlax-invoke obj3 'intersectwith obj1 1))
(or (vla-move obj3 (vlax-3d-point (vlax-get obj3 'startpoint))(vlax-3d-point p1new)) 1)
(setq e3 (vlax-vla-object->ename obj3))
(setq p3new (vlax-invoke obj4 'intersectwith obj1 1))
(or (vla-move obj4 (vlax-3d-point (vlax-get obj4 'startpoint))(vlax-3d-point p3new)) 1)
(setq e4 (vlax-vla-object->ename obj4))
(vl-cmdf "_.trim" e3 "" p2 "")
(vl-cmdf "_.trim" e4 "" p4 "")
(setq ent (append (entget e2) '((8 . "A-ELEV"))))
(entmod ent)
(vl-cmdf "_.pedit" e2 "_J" e3 e4 "" "")
(princ "\nDONE!")
)
(*error* nil)
)
John F. Uhden
Interesting. I like the way it works and the fact that it keeps the end lines vertical.
It seems to do some odd spacing and missed some of the cleanup at ends?
@DC-MWA ,
I emulated your polyline and got a good result:
Yes, I had set layer "A-ELEV" to color 1. Note that if the layer had not existed that (entmod) will create it.
I am guessing there may be a difference in the TRIM command between the 2002 and more recent AutoCAD releases. So that there is no confusion, could you please post a 2000 version of your polyline dwg?
Ya know, it could be that you were zoomed in such that the endpoints were out of view. I think that AutoCAD needs to "see" the ends in order to trim them. Please try zooming out and trying again.
Yep, I just tested and what I suspect is true. So either you live with the zooming requirement or else I have to figure out a different approach. Oh, yeah. I just wrote one for the MBREAK16 routine. It contains a subfunction to zoom out prior to processing.
John F. Uhden
@DC-MWA ,
Nevermind. This enhanced version solves the zoom problem.
(defun c:screed3 ( / *error* vars vals e1 obj1 e2 obj2 e3 obj3
e4 obj4 p1 p2 p3 p4 d @checkzoom)
(gc)
(vl-load-com)
(princ "SCREED3 v1.01 (c)2024, John F. Uhden for @DC-MWA.\n")
;; added @checkzoom function to bring endpoints within view
(defun *error* (err)
(mapcar 'setvar vars vals)
(vla-endundomark *doc*)
(cond
((not err))
((wcmatch (strcase err) "*CANCEL*,*QUIT*"))
(1 (princ (strcat "\nERROR: " err)))
)
(princ)
)
(or *acad* (setq *acad* (vlax-get-acad-object)))
(or *doc* (setq *doc* (vla-get-ActiveDocument *acad*)))
(vla-endundomark *doc*)
(vla-startundomark *doc*)
(setq vars '("cmdecho" "osmode"))
(setq vals (mapcar 'getvar vars))
(mapcar 'setvar vars '(0 0))
(command "_.expert" (getvar "expert")) ;; dummy command
(defun @checkzoom (ss / i ent pts xmin ymin xmax ymax xmin! ymin! xmax! ymax!)
(repeat (setq i (sslength ss))
(setq ent (entget (ssname ss (setq i (1- i)))))
(setq pts (append pts (mapcar 'cdr (vl-remove-if-not '(lambda (x)(vl-position (car x)'(10 11))) ent))))
)
(setq xmin (apply 'min (mapcar 'car pts))
ymin (apply 'min (mapcar 'cadr pts))
xmax (apply 'max (mapcar 'car pts))
ymax (apply 'max (mapcar 'cadr pts))
xmin! (- xmin (* 0.1 (- xmax xmin)))
ymin! (- ymin (* 0.1 (- ymax ymin)))
xmax! (+ xmax (* 0.1 (- xmax xmin)))
ymax! (+ ymax (* 0.1 (- ymax ymin)))
)
(vl-cmdf ".zoom" "_W" (list xmin! ymin!)(list xmax! ymax!))
)
(and ;; the Stephan Koster approach
(setq e1 (car (entsel "\nSelect surface LWpolyline: ")))
(setq obj1 (vlax-ename->vla-object e1))
(setq p1 (vlax-curve-getstartpoint obj1))
(setq p3 (vlax-curve-getendpoint obj1))
(or
(> (abs (apply '- (mapcar 'car (list p1 p3)))) 3)
(prompt "\nObject is not wide enough.")
)
(not (initget 6))
(or (setq d (getdist "\nDepth to bottom <4.0>: "))
(setq d 4.0)
)
(setq obj2 (vla-copy obj1))
(setq e2 (vlax-vla-object->ename obj2))
(or (vla-move obj2 (vlax-3d-point '(0 0 0))(vlax-3d-point (list 0 (- d) 0))) 1)
(@checkzoom (ssadd e2))
(setq p2 (mapcar '- p1 (list 0 d 0)))
(setq e3 (entmakex (list '(0 . "LINE")(cons 10 p1)(cons 11 p2))))
(setq obj3 (vlax-ename->vla-object e3))
(setq p4 (mapcar '- p3 (list 0 d 0)))
(setq e4 (entmakex (list '(0 . "LINE")(cons 10 p3)(cons 11 p4))))
(setq obj4 (vlax-ename->vla-object e4))
(if (> (car p3)(car p1))
(progn
(or (vla-move obj3 (vlax-3d-point '(0 0 0))(vlax-3d-point (list 1.5 0 0))) 1)
(or (vla-move obj4 (vlax-3d-point '(0 0 0))(vlax-3d-point (list -1.5 0 0))) 1)
)
(progn
(or (vla-move obj3 (vlax-3d-point '(0 0 0))(vlax-3d-point (list -1.5 0 0))) 1)
(or (vla-move obj4 (vlax-3d-point '(0 0 0))(vlax-3d-point (list 1.5 0 0))) 1)
)
)
(setq p1new (vlax-invoke obj3 'intersectwith obj1 1))
(or (vla-move obj3 (vlax-3d-point (vlax-get obj3 'startpoint))(vlax-3d-point p1new)) 1)
(setq e3 (vlax-vla-object->ename obj3))
(setq p3new (vlax-invoke obj4 'intersectwith obj1 1))
(or (vla-move obj4 (vlax-3d-point (vlax-get obj4 'startpoint))(vlax-3d-point p3new)) 1)
(setq e4 (vlax-vla-object->ename obj4))
(vl-cmdf "_.trim" e3 "" p2 "")
(vl-cmdf "_.trim" e4 "" p4 "")
(setq ent (append (entget e2) '((8 . "A-ELEV"))))
(entmod ent)
(vl-cmdf "_.pedit" e2 "_J" e3 e4 "" "")
(princ "\nDONE!")
)
(*error* nil)
)
z
John F. Uhden
Hi John,
I tried it and I'm still getting odd spacing and the cleanup issue.
See below...
I am sending you a drawing as request.
Can't find what you're looking for? Ask the community or share your knowledge.