sublimation Posted May 8, 2021 Posted May 8, 2021 (edited) I'm beginning to feel lost in the woods with my program. The idea was to create marks at every straight wall segment of the profile to take measurements later when machined. It has turned into a hot mess of frustration. This was done manually and very much the expected outcome. This is what I got. It's close and I was pretty happy with the results. And if this were the consistent result, I would be feeling pretty confident. However.... When I tried my program on other profiles, I got this: And this: On these profiles, even if it's placing circles correctly between the walls, it's still not placing all the circles. I'm not sure where I need help with this code and whether I should start over from scratch or if I can fix it (there is a lot of duct-taped code in there). If my code and/or logic is bad, I'm completely open to starting from scratch with new suggestions. My logic is obviously not working, and I thought maybe someone else might see this and have a different way of approaching it. Code description. There are two ways to use this code. Preselecting everything & automating the entire profile, and adding single marks. The single method I think reads well, but not the automatic so I will explain my logic. First it sorts the geometry by area so that I could tackle the problem from inside to outside. Takes each single line and checks if there is another line within the typical range of wall thicknesses and (mostly) parallel to itself nearby Checks the new selection for it's position in the previous lists (to avoid duplicate circles) Checks which points of the new line "overlap" and the length of the "overlap" [longer the line, the more circles] Get psuedo points for establishing circles. Generate circles and dimensions. If I haven't explained this well, please let me know! Note: For readability, if you are pasting this into an editor, I use 4 spaces per tab. Thank you all for taking a look at this! I am very grateful for any suggestions you might have to modify or completely replace my code so I can get it working properly! I have attached a dwg with the profile geometry incase there is an issue with them. Edited May 24, 2021 by sublimation Quote
rlx Posted May 11, 2021 Posted May 11, 2021 Your code is probably too complex for us mortals , well it is for me , there I said it... Still it's impressive even if it's not stable (yet). Looks like the leader part itself is working but the circle part is not. Maybe you could try to use ssget with 2-point fence instead of crossing , once with polar 0 degrees and once polar 0.5pi and then someting like vla-intersectWith , find midpoint between intersection. (don't think I have ever programmed something with vla-intersectWith myself or maybe I have but Altzheimer) Anyways , maybe create a better / simpler test environment with very simple squares where all coordinates are known , and print or place breakpoint / watch for all values and coordinates so you know exactly what values you should expect to see. And once you got this working move on to more complex figures. I expected more response for your thread so maybe my reaction triggers more (/ more intelligent) people to have a look at your code because I think its worth it. I know I have seen something simular on this site but can't find it. Dont know the right english words to search for , markers , leaders with circle, autonumber parts? hope you will get more reactions but sometimes its very hard to follow someone elses code / thoughts / logic you know , hell I sometimes have trouble deciphering my own code after a while. Good luck. 1 Quote
ronjonp Posted May 11, 2021 Posted May 11, 2021 You'll need to add this to the code to even get it to run: (setq {acadapp} (vlax-get-acad-object) {acaddoc} (vla-get-activedocument {acadapp}) {modelspace} (vla-get-modelspace {acaddoc}) ) Why have you chosen dimensions like this for these callouts ? It's a bit busy IMO. Maybe use mleaders then you can use mleaderalign to line them up ? 1 Quote
sublimation Posted May 12, 2021 Author Posted May 12, 2021 14 hours ago, rlx said: Your code is probably too complex for us mortals , well it is for me , there I said it... Still it's impressive even if it's not stable (yet). I think I made it more complex than needed too. Looking back I defined a function to sort by area, I use it once, and it's one line. Why? 14 hours ago, rlx said: Looks like the leader part itself is working but the circle part is not. Maybe you could try to use ssget with 2-point fence instead of crossing , once with polar 0 degrees and once polar 0.5pi and then someting like vla-intersectWith , find midpoint between intersection. (don't think I have ever programmed something with vla-intersectWith myself or maybe I have but Altzheimer) I will definitely check that out. 14 hours ago, rlx said: hope you will get more reactions but sometimes its very hard to follow someone elses code / thoughts / logic you know , hell I sometimes have trouble deciphering my own code after a while. Good luck. Same here. In part because I am horrible at documenting my code. 14 hours ago, ronjonp said: You'll need to add this to the code to even get it to run: (setq {acadapp} (vlax-get-acad-object) {acaddoc} (vla-get-activedocument {acadapp}) {modelspace} (vla-get-modelspace {acaddoc}) ) I do establish those variables in a program that initializes some system settings. So many files are shared with so many other designers that I force my standard on all incoming drawings before I have to look at them. These variables are a part that that program. My apologies for not mentioning that in me initial post. 14 hours ago, ronjonp said: Why have you chosen dimensions like this for these callouts ? It's a bit busy IMO. Maybe use mleaders then you can use mleaderalign to line them up ? I will look into that. I don't understand why placing the dia. dimension is so difficult in autolisp; the textposition trait doesn't seem to line up with the coordinates I put in. Maybe mleader will work better. Thank you both for giving this a look! I really appreciate it! Quote
rlx Posted May 12, 2021 Posted May 12, 2021 Have many appies that are doing great but if I ever have to change anything probably better to start from scratch. That's why I often use many subfunctions so I only have to take that part out and replace it with a better version. In your case you may want to make a subfunction that can find the midpoint between 2 parallel (poly)lines , taking in account general spacing if this is known and angle of the lines / polyline segments. Just using one of the standard AutoCad (M)leader styles would also get you a long way. But I understand , nobody wants to kick out their 'baby' they have nurtured for so long... 1 Quote
sublimation Posted May 12, 2021 Author Posted May 12, 2021 1 hour ago, rlx said: Have many appies that are doing great but if I ever have to change anything probably better to start from scratch. Sadly, I have already started doing that. Hopefully it's my code that's bad and not my logic because I am reusing that. I'm not sure of any other way to approach the problem. Quote
rlx Posted May 13, 2021 Posted May 13, 2021 (edited) not exactly a solution but added a little sub to represent all points with donut to see what's happening. Known issue with ssget is that your zoom level can matter when selecting things and sometimes selecting a point fails when zoomed out and works when zoomed in. Hope it helps a tiny little bit... oh p.s. sorry about the formatting , not saying yours is wrong , just having my own preferences... wallpins.lsp Edited May 13, 2021 by rlx Quote
sublimation Posted May 13, 2021 Author Posted May 13, 2021 38 minutes ago, rlx said: not exactly a solution but added a little sub to represent all points with donut to see what's happening. Known issue with ssget is that your zoom level can matter when selecting things and sometimes selecting a point fails when zoomed out and works when zoomed in. Hope it helps a tiny little bit... Thank you! I look forward to studying it. 38 minutes ago, rlx said: oh p.s. sorry about the formatting , not saying yours is wrong , just having my own preferences... Totally get it! Quote
ronjonp Posted May 13, 2021 Posted May 13, 2021 Maybe this will give you some ideas: (defun c:foo (/ a b c d e i l mp o p p2 s) (setq d 0.075) (if (setq s (ssget "_X" '((0 . "LWPOLYLINE")))) (progn (setq s (mapcar 'cadr (ssnamex s))) (while (setq p (getpoint "\nPick a point:")) (setq a (mapcar '(lambda (e) (list (setq p2 (vlax-curve-getclosestpointto e p)) (distance p p2) e)) s ) ) (setq a (vl-sort a '(lambda (r j) (< (cadr r) (cadr j))))) (cond ((< (cadar a) d) (setq o (vlax-ename->vla-object (last (car a)))) (mapcar 'set '(b c) (mapcar 'car a)) (setq mp (mapcar '/ (mapcar '+ b c) '(2 2 2))) (setq l (entmakex (list '(0 . "LINE") (cons 10 (polar p (angle p b) d)) (cons 11 (polar p (angle b p) d)) '(8 . "templayer") ) ) ) (setq i (vlax-invoke o 'intersectwith (vlax-ename->vla-object l) 0)) (entdel l) (if (= 6 (length i)) (setq b (mapcar '+ i '(0 0 0)) c (mapcar '+ (cdddr i) '(0 0 0)) mp (mapcar '/ (mapcar '+ b c) '(2 2 2)) ) ) (entmakex (list '(0 . "CIRCLE") (cons 10 mp) (cons 40 (/ (distance b c) 2)) '(62 . 3))) ) ) ) ) ) ) (vl-load-com) 1 1 Quote
ronjonp Posted May 13, 2021 Posted May 13, 2021 3 minutes ago, rlx said: nicely done Ronjonp Thanks Quote
sublimation Posted May 13, 2021 Author Posted May 13, 2021 1 hour ago, ronjonp said: Maybe this will give you some ideas: (defun c:foo (/ a b c d e i l mp o p p2 s) (setq d 0.075) (if (setq s (ssget "_X" '((0 . "LWPOLYLINE")))) (progn (setq s (mapcar 'cadr (ssnamex s))) (while (setq p (getpoint "\nPick a point:")) (setq a (mapcar '(lambda (e) (list (setq p2 (vlax-curve-getclosestpointto e p)) (distance p p2) e)) s ) ) (setq a (vl-sort a '(lambda (r j) (< (cadr r) (cadr j))))) (cond ((< (cadar a) d) (setq o (vlax-ename->vla-object (last (car a)))) (mapcar 'set '(b c) (mapcar 'car a)) (setq mp (mapcar '/ (mapcar '+ b c) '(2 2 2))) (setq l (entmakex (list '(0 . "LINE") (cons 10 (polar p (angle p b) d)) (cons 11 (polar p (angle b p) d)) '(8 . "templayer") ) ) ) (setq i (vlax-invoke o 'intersectwith (vlax-ename->vla-object l) 0)) (entdel l) (if (= 6 (length i)) (setq b (mapcar '+ i '(0 0 0)) c (mapcar '+ (cdddr i) '(0 0 0)) mp (mapcar '/ (mapcar '+ b c) '(2 2 2)) ) ) (entmakex (list '(0 . "CIRCLE") (cons 10 mp) (cons 40 (/ (distance b c) 2)) '(62 . 3))) ) ) ) ) ) ) (vl-load-com) DUDE! You just simplified a very stressful part of my code. I just need to do a little tweaking to make it useable in both section. Thank you! Also, how does this work if nothing is passed to it when defined? (vl-sort a '(lambda (r j) (< (cadr r) (cadr j)))) Quote
ronjonp Posted May 13, 2021 Posted May 13, 2021 25 minutes ago, sublimation said: Also, how does this work if nothing is passed to it when defined? (vl-sort a '(lambda (r j) (< (cadr r) (cadr j)))) Not sure I understand the question? It is sorting the list 'a' created in the line above by shortest distance. 26 minutes ago, sublimation said: DUDE! You just simplified a very stressful part of my code. I just need to do a little tweaking to make it useable in both section. Thank you! You're welcome Quote
sublimation Posted May 13, 2021 Author Posted May 13, 2021 11 minutes ago, ronjonp said: Not sure I understand the question? It is sorting the list 'a' created in the line above by shortest distance. Nevermind. In my excitement I misread it expecting a variable after the lambda function. Quote
ronjonp Posted May 13, 2021 Posted May 13, 2021 Here's another for fun .. works pretty well on geometry with many internal islands but doesn't do the self intersecting areas. (defun c:foo (/ a d e mp n o p p2 s x) ;; RJP » 2021-05-13 (setq d 0.075) (if (setq s (ssget "_X" '((0 . "LWPOLYLINE")))) (progn (setq s (mapcar 'cadr (ssnamex s))) (setq s (mapcar '(lambda (e) (list e (vlax-curve-getarea e))) s)) (setq s (mapcar 'car (vl-sort s '(lambda (r j) (< (cadr r) (cadr j)))))) (while (cadr s) (setq e (car s)) (setq s (cdr s)) (repeat (setq n (fix (vlax-curve-getendparam e))) (setq p (vlax-curve-getpointatparam e (- n 0.5))) (if (= 0 (vla-getbulge (vlax-ename->vla-object e) (fix (- n 0.5)))) (progn (setq a (mapcar '(lambda (x) (list (setq p2 (vlax-curve-getclosestpointto x p)) (distance p p2) e) ) s ) ) (setq a (vl-sort a '(lambda (r j) (< (cadr r) (cadr j))))) (cond ((< (cadar a) d) (grdraw (caar a) p 3) (setq o (vlax-ename->vla-object (last (car a)))) (setq mp (mapcar '/ (mapcar '+ (caar a) p) '(2 2 2))) (entmakex (list '(0 . "CIRCLE") (cons 10 mp) (cons 40 (/ (distance (caar a) p) 2)) '(62 . 3) ) ) (entmakex (list '(0 . "TEXT") '(100 . "AcDbEntity") '(8 . "DiameterText") '(100 . "AcDbText") '(62 . 1) (cons 10 mp) (cons 40 (/ (distance (caar a) p) 4)) (cons 1 (vl-string-right-trim "0" (strcat "%%C" (rtos (distance (caar a) p) 2 4))) ) '(50 . 0.) '(7 . "Standard") '(71 . 0) '(72 . 1) (cons 11 mp) '(100 . "AcDbText") '(73 . 2) ) ) ) ) ) ) (setq n (1- n)) ) ) ) ) ) (vl-load-com) 2 Quote
sublimation Posted May 14, 2021 Author Posted May 14, 2021 15 hours ago, ronjonp said: Here's another for fun .. works pretty well on geometry with many internal islands but doesn't do the self intersecting areas. (defun c:foo (/ a d e mp n o p p2 s x) ;; RJP » 2021-05-13 (setq d 0.075) (if (setq s (ssget "_X" '((0 . "LWPOLYLINE")))) (progn (setq s (mapcar 'cadr (ssnamex s))) (setq s (mapcar '(lambda (e) (list e (vlax-curve-getarea e))) s)) (setq s (mapcar 'car (vl-sort s '(lambda (r j) (< (cadr r) (cadr j)))))) (while (cadr s) (setq e (car s)) (setq s (cdr s)) (repeat (setq n (fix (vlax-curve-getendparam e))) (setq p (vlax-curve-getpointatparam e (- n 0.5))) (if (= 0 (vla-getbulge (vlax-ename->vla-object e) (fix (- n 0.5)))) (progn (setq a (mapcar '(lambda (x) (list (setq p2 (vlax-curve-getclosestpointto x p)) (distance p p2) e) ) s ) ) (setq a (vl-sort a '(lambda (r j) (< (cadr r) (cadr j))))) (cond ((< (cadar a) d) (grdraw (caar a) p 3) (setq o (vlax-ename->vla-object (last (car a)))) (setq mp (mapcar '/ (mapcar '+ (caar a) p) '(2 2 2))) (entmakex (list '(0 . "CIRCLE") (cons 10 mp) (cons 40 (/ (distance (caar a) p) 2)) '(62 . 3) ) ) (entmakex (list '(0 . "TEXT") '(100 . "AcDbEntity") '(8 . "DiameterText") '(100 . "AcDbText") '(62 . 1) (cons 10 mp) (cons 40 (/ (distance (caar a) p) 4)) (cons 1 (vl-string-right-trim "0" (strcat "%%C" (rtos (distance (caar a) p) 2 4))) ) '(50 . 0.) '(7 . "Standard") '(71 . 0) '(72 . 1) (cons 11 mp) '(100 . "AcDbText") '(73 . 2) ) ) ) ) ) ) (setq n (1- n)) ) ) ) ) ) (vl-load-com) I really need to learn these vlax functions. I think if I had started with something like that I could have eliminated about a week off of my coding time. Quote
ronjonp Posted May 14, 2021 Posted May 14, 2021 3 hours ago, sublimation said: I really need to learn these vlax functions. I think if I had started with something like that I could have eliminated about a week off of my coding time. Well hope you can learn from it Quote
sublimation Posted May 17, 2021 Author Posted May 17, 2021 (edited) Well I am finally mostly done. It's a good 99% effective, though I still have some tweaks and features to add. Thank you everyone for your help. If anyone is interested in the program or wants to scavenge code, here it is: Couple of the glitches: No circle created. Bad circle Bad placement. Other than those for the automated option, its not bad. Edited May 24, 2021 by sublimation Quote
Recommended Posts
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.