Lee Mac Posted December 28, 2008 Share Posted December 28, 2008 Hi Guys, Hope you are all having a great Christmas, and have a equally good New Year. Just a quick question, which I am sure can be answered in minutes. When looking at a problem posted on here recently (about marking points on a golf course...), I was thinking how I would approach the problem, and thought about using the vertices of a user-drawn polyline. To experiment, I drew myself a polyline (attached), and performed an entget operation on it to see what it would return. This is the result: ((-1 . <Entity name: 7ef62ed8>) [color=Purple][b](0 . "LWPOLYLINE") <<--- Entity Type[/b][/color] (330 . <Entity name: 7ef53cc0>) (5 . "2DC3") (100 . "AcDbEntity") (67 . 0) [b][color=Orange](410 . "Model") [/color][color=Orange]<<--- Tab Name[/color][/b] [b][color=YellowGreen](8 . "3") [/color][color=YellowGreen]<<--- Layer Name[/color][/b] (100 . "AcDbPolyline") (90 . 4) (70 . 0) (43 . 0.0) (38 . 0.0) (39 . 0.0) [color=Red][b] (10 0.0 0.0)[/b][/color] [b][color=Red]<<--- First Vertex (Start Point)[/color][/b] [b][color=RoyalBlue](40 . 0.0) [/color][color=RoyalBlue]<<--- Starting Thickness for First Segment[/color][/b] [b][color=SeaGreen](41 . 0.0) [/color][color=SeaGreen]<<--- Ending Thickness for First Segment[/color][/b] (42 . 0.0) [b][color=Red](10 10.0 0.0)[/color][/b] [b][color=Red]<<--- Second Vertex[/color][/b] [b][color=RoyalBlue](40 . 0.0)[/color] [color=SeaGreen](41 . 0.0)[/color][/b] (42 . 0.0) [b][color=Red](10 10.0 10.0)[/color][/b] [b][color=Red]<<--- Third Vertex[/color][/b] [b][color=RoyalBlue](40 . 0.0)[/color] [color=SeaGreen](41 . 0.0)[/color][/b] (42 . 0.0) [b][color=Red](10 0.0 10.0)[/color][/b] [b][color=Red]<<--- Fourth Vertex (End Point)[/color][/b] [b][color=RoyalBlue](40 . 0.0)[/color] [color=SeaGreen](41 . 0.0)[/color][/b] (42 . 0.0) (210 0.0 0.0 1.0)) These coordinates correspond to the various vertices on my attached drawing. But my question is, how does one obtain these values through LISP? My initial assumption would be something of the form: (defun c:test (/ ent Vertex) (setq ent (entget (car (entsel)))) (setq Vertex (cdr (assoc [b][color=Red]10[/color][/b] ent))) (princ) ) ;_ end defun But how would one retrieve the next vertex, and every other vertex after that? How do you cycle through the different entries for the DXF code 10? Many thanks for any advice and help provided Quote Link to comment Share on other sites More sharing options...
ASMI Posted December 28, 2008 Share Posted December 28, 2008 Try in command line: Click polyline to get DXF list: Command: (setq plDxf(entget(car(entsel)))) Select object: ((-1 . <Entity name: 7efa3368>) (0 . "LWPOLYLINE") (330 . <Entity name: 7efa1cf8>) (5 . "1AD") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbPolyline") (90 . 4) (70 . 0) (43 . 0.0) (38 . 0.0) (39 . 0.0) (10 0.0 0.0) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 10.0 0.0) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 10.0 10.0) (40 . 0.0) (41 . 0.0) (42 . 0.0) (10 0.0 10.0) (40 . 0.0) (41 . 0.0) (42 . 0.0) (210 0.0 0.0 1.0)) Remove all non 10 groups: Command: (setq lst10(vl-remove-if '(lambda(x)(/= 10(car x)))plDxf)) ((10 0.0 0.0) (10 10.0 0.0) (10 10.0 10.0) (10 0.0 10.0)) Remove first member of each list" Command: (setq verLst(mapcar 'cdr lst10)) ((0.0 0.0) (10.0 0.0) (10.0 10.0) (0.0 10.0)) Or at once: Command: (mapcar 'cdr(vl-remove-if '(lambda(x)(/= 10(car x)))(entget(car(entsel))))) ((0.0 0.0) (10.0 0.0) (10.0 10.0) (0.0 10.0)) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted December 28, 2008 Author Share Posted December 28, 2008 Thank you for your reply, ASMI - I have learnt a lot from it. But, I note that this would only work for this example - for instance, if I had vertices with co-ordinates: (1.0 5.0 0.0) (2.0 6.0 0.0) (3.0 7.0 0.0) How would I deal with this situation? Is there not a generic function for dealing with multiple occurences of the same DXF group code? Thanks for your help ASMI, much appreciated. Quote Link to comment Share on other sites More sharing options...
ASMI Posted December 28, 2008 Share Posted December 28, 2008 It will work with every lwpolyline. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted December 28, 2008 Author Share Posted December 28, 2008 Ahh, Sorry, I misread you last post - when you removed the DXF 10 code. Sorry! And thanks for your help! Quote Link to comment Share on other sites More sharing options...
lpseifert Posted December 28, 2008 Share Posted December 28, 2008 This may interest you... http://www.theswamp.org/index.php?topic=23951.0 Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted December 28, 2008 Author Share Posted December 28, 2008 Thanks lpseifert, Thats very interesting! Quote Link to comment Share on other sites More sharing options...
David Bethel Posted December 28, 2008 Share Posted December 28, 2008 (defun massoc (key alist / x nlist) (foreach x alist (if (eq key (car x)) (setq nlist (cons (cdr x) nlist)))) (reverse nlist)) This will return a list of values for the key in alist. It was made to deal with just such a scenario. You would have to do some extra coding for every other one etc. -David Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted December 28, 2008 Author Share Posted December 28, 2008 Excellent David, Simple and effective. Nice one Thanks Quote Link to comment Share on other sites More sharing options...
KRBeckman Posted February 8, 2010 Share Posted February 8, 2010 I might be missing something here, but would it be possible to take the points taken from the polyline and save them as pt1, pt2, pt3.... so they can be used in another command? Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 8, 2010 Author Share Posted February 8, 2010 I might be missing something here, but would it be possible to take the points taken from the polyline and save them as pt1, pt2, pt3.... so they can be used in another command? Wow... this is an old thread - takes me back to when I started learning all this.. As for your question - all the point data is in the resulting list, so you could assign your variables from that. But I would approach it differently and use vlax-curve-getPointatParam as you have much more control. Quote Link to comment Share on other sites More sharing options...
KRBeckman Posted February 9, 2010 Share Posted February 9, 2010 I tried to search Visual Lisp's help and google for this and I can only find examples of it being used that went way over my head... do you mind showing me an example of using this function and break it down step by step how it works? Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 9, 2010 Author Share Posted February 9, 2010 Each curve object is 'divided' by a parameter, you can look at it as the parameter in a set of parametric equations that would describe the curve if you like, so for a circle: x = r cos(t) y = r sin(t) Where, in this case, t is the parameter. The curve functions allow you to get a point for a specific parameter value. In the case of LWPolylines, each segment spans between two integer values of the parameter, hence each vertex is at an integer parameter value. This gives you a lot of control when getting specific parameter values, as you can just 'count' the vertices. Example: (defun c:test (/ ent i pt) (setvar "PDMODE" 34) (if (setq ent (car (entsel "\nSelect LWPolyline: "))) (progn (setq i (1- (vlax-curve-getStartParam ent))) (while (setq pt (vlax-curve-getPointatParam ent (setq i (1+ i)))) (entmakex (list (cons 0 "POINT") (cons 10 pt)))))) (princ)) Quote Link to comment Share on other sites More sharing options...
CAB Posted February 9, 2010 Share Posted February 9, 2010 A long winded example. (defun c:test (/ ent idx pt startParam endParam) (setvar "PDMODE" 34) (if (setq ent (car (entsel "\nSelect LWPolyline: "))) (progn (setq startParam (vlax-curve-getStartParam ent)) ; this is usually zero (setq endParam (vlax-curve-getEndParam ent)) (setq idx startParam) (while (<= idx endParam) ; loop until we get to the last param (setq pt (vlax-curve-getPointatParam ent idx)) (entmakex (list (cons 0 "POINT") (cons 10 pt))) (cond ((= idx endParam) (setq idx (1+ idx)) ; force an exit of the loop ) ((> (setq idx (1+ idx)) ; next param endParam) ; test to see of we are past the end Param (setq idx endParam) ; in case the last param is a fraction ) ) ) ) ) (princ) ) Quote Link to comment Share on other sites More sharing options...
KRBeckman Posted February 9, 2010 Share Posted February 9, 2010 Wow, way over my head, I still have a lot to learn Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 9, 2010 Author Share Posted February 9, 2010 Wow, way over my head, I still have a lot to learn I would recommend persevering with the curve-functions, they are a handy (and quick!) asset in your toolbox Quote Link to comment Share on other sites More sharing options...
KRBeckman Posted February 12, 2010 Share Posted February 12, 2010 So, I've looked into this a bunch and I'm not getting anywhere... How would I use the vlax-curve-getPointatParam function to save the vertices as pt1, pt2, pt3....? Quote Link to comment Share on other sites More sharing options...
CAB Posted February 12, 2010 Share Posted February 12, 2010 All you need is a LIST of points, correct? This returns a list of points from the entity list of a LWPolyline. (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= 10 (car x))) elst)) Use it like this: (defun c:test() (setq ent (car(entsel "\nSelect a polyline."))) (setq elst (entget ent)) (setq PointList (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= 10 (car x))) elst))) (princ) ) You don't need to assign each point to a variable. Tell us what you want to do with these points. Quote Link to comment Share on other sites More sharing options...
KRBeckman Posted February 12, 2010 Share Posted February 12, 2010 Code: (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= 10 (car x))) elst)) Yeah, I've gotten this far... Tell us what you want to do with these points. I want to use these points in filling the Polyline with 3d-Faces Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted February 12, 2010 Author Share Posted February 12, 2010 Wasn't this being addressed here? http://www.cadtutor.net/forum/showthread.php?t=44611 Quote Link to comment Share on other sites More sharing options...
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.