chulse Posted April 27, 2012 Share Posted April 27, 2012 Could someone help point me in the right direction here? I want to filter a selection of polylines (contour lines) by their Z value (ie filter to get only 10' or 5' or 2' contours). I assume I need to test the Z value to see if it is a muliple of 10, 5 or 2, etc... Any hints on hhow to get this sarted? Thanks Quote Link to comment Share on other sites More sharing options...
David Bethel Posted April 27, 2012 Share Posted April 27, 2012 Are these LWPOLYLINES or Heavy POLYLINEs ? -David Quote Link to comment Share on other sites More sharing options...
chulse Posted April 27, 2012 Author Share Posted April 27, 2012 I'm not sure. I'll have to find out - i'm working on this for my sister. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 27, 2012 Share Posted April 27, 2012 To check the Polyline type, load this and pick a Polyline: (defun c:checkpoly ( / e ) (if (setq e (car (entsel))) (print (cdr (assoc 0 (entget e)))) ) (princ) ) If the above returns "LWPOLYLINE", you can filter the selection by the LWPolyline Elevation value, DXF 38: (ssget "_X" '((0 . "LWPOLYLINE") (38 . <YourElevationValue>))) If the above returns "POLYLINE", things are a little more complicated, since the Z value will be contained in the coordinate of each vertex. Such vertices are not primary entities and hence cannot be filtered using an ssget filter list. For this case, you would need to collect a set of all such Polylines, then iterate over this set removing those which do not have the correct vertex elevation. Quote Link to comment Share on other sites More sharing options...
chulse Posted April 27, 2012 Author Share Posted April 27, 2012 Thanks guys. I'll have to get one of her drawings and play with it. Quote Link to comment Share on other sites More sharing options...
pBe Posted April 27, 2012 Share Posted April 27, 2012 Sample Code (defun c:test (/ elev ss) (initget 1 "2 5 10 ALL") (setq elev (getkword "\nSelect String for filter [2/5/10/ALL]: ")) (setq ss (ssget "_X" (if (eq elev "ALL") '((0 . "LWPOLYLINE") (-4 . "<OR") (38 . 24.0) (38 . 60.0) (38 . 120.0) (-4 . "OR>") ) (list '(0 . "LWPOLYLINE") (cons 38 (* 12 (distof elev))) ) ) ) ) (sssetfirst nil ss) ) Quote Link to comment Share on other sites More sharing options...
chulse Posted April 28, 2012 Author Share Posted April 28, 2012 Thanks pBe. You must be an architect - it took me a few to realize you were looking at inches. These are topo contour lines (all in feet). I think I managed to work out the general concept, but I am getting an error with the SSGET list. (bad SSGET list) What I need to do (I think) is step through all possible 10' elevations and add each to a SS as we go. In the end, the goal is to find all of them (any elvation that's a multiple of 10) and move it to a specific layer. (setq elev 10) (while (<= elev 10000) (setq temp (ssget "_X" '((0 . "LWPOLYLINE") (cons '38 elev)))) (setq ss (ssadd ss temp)) (setq temp nil) (setq elev (+ elev 10)) );_end while I'm a bit stumped why I am getting the error. Any help much appericated. Thanks Quote Link to comment Share on other sites More sharing options...
pBe Posted April 28, 2012 Share Posted April 28, 2012 Try this way [b][color=blue](defun c:demo (/ elev ss i)[/color][/b] (setq elev 10 [color=blue][b]ss (ssadd)[/b][/color][color=black])[/color] (while (<= elev 10000) [color=blue][b] (if (setq temp (ssget "_X" (List '(0 . "LWPOLYLINE") (cons 38 elev))))[/b][/color] [color=blue][b](repeat (setq i (sslength temp))[/b][/color] [color=blue][b] (ssadd (ssname temp (setq i (1- i))) ss)))[/b][/color] (setq elev (+ elev 10)) );_end while [b][color=blue](sssetfirst nil ss)[/color][/b] ) I guess you guys use DECIMAL Feet, I seldom deal with units other than architectural , only when i'm "forced" to do grading. Quote Link to comment Share on other sites More sharing options...
chulse Posted April 28, 2012 Author Share Posted April 28, 2012 thanks Yes, everything is decimal, so I didn't realize at first what your code was doing Quote Link to comment Share on other sites More sharing options...
pBe Posted April 28, 2012 Share Posted April 28, 2012 you might find this one interesting though (defun c:demo (/ elev ss) (setq elev 10 ss (ssadd)) (while (<= elev 10000) (if (setq temp (ssget "_X" (List '(0 . "LWPOLYLINE") [color=blue][b]'(-4 . "<OR")[/b][/color] [b][color=blue] (cons 38 elev)[/color][/b] [b][color=blue] (cons 38 (- elev))[/color][/b] [b][color=blue] '(-4 . "OR>")[/color][/b] ))) (repeat (setq i (sslength temp)) (ssadd (ssname temp (setq i (1- i))) ss))) (setq elev (+ elev 10)) ) ;_end while (sssetfirst nil ss) ) It includes negative intervall of 10 as well Quote Link to comment Share on other sites More sharing options...
chulse Posted April 28, 2012 Author Share Posted April 28, 2012 cool, although i don't think i'll ever need to deal with elevations below sea level (at least not on the east coast of the US) My next issue is this - i assumed i could use FOREACH to set the layer of the entities in the SS, but it seems not. is the concept bad or just my syntax? ;put 10' contours on correct new layer (foreach obj SS (vla-put-layer obj Lay10) );_end foreach it returns this "** Error: bad argument type: consp **" Quote Link to comment Share on other sites More sharing options...
David Bethel Posted April 28, 2012 Share Posted April 28, 2012 My guess is that it would be simple just to step through a PICKSET of LWPOLYLINEs [b][color=BLACK]([/color][/b]defun c:topten [b][color=FUCHSIA]([/color][/b]/ ss en[b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]setq s1 [b][color=NAVY]([/color][/b]ssadd[b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]and [b][color=NAVY]([/color][/b]setq ss [b][color=MAROON]([/color][/b]ssget '[b][color=GREEN]([/color][/b][b][color=BLUE]([/color][/b]0 . [color=#2f4f4f]"LWPOLYLINE"[/color][b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] [b][color=NAVY]([/color][/b]while [b][color=MAROON]([/color][/b]setq en [b][color=GREEN]([/color][/b]ssname ss 0[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]if [b][color=GREEN]([/color][/b]zerop [b][color=BLUE]([/color][/b]rem [b][color=RED]([/color][/b]cdr [b][color=PURPLE]([/color][/b]assoc 38 [b][color=TEAL]([/color][/b]entget en[b][color=TEAL])[/color][/b][b][color=PURPLE])[/color][/b][b][color=RED])[/color][/b] 10[b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] [b][color=GREEN]([/color][/b]ssadd en s1[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b] [b][color=MAROON]([/color][/b]ssdel en ss[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b] s1[b][color=BLACK])[/color][/b] Even if you select _All -David Quote Link to comment Share on other sites More sharing options...
pBe Posted April 28, 2012 Share Posted April 28, 2012 My guess is that it would be simple just to step through a PICKSET of LWPOLYLINEs .......(zerop (rem (cdr (assoc 38 (entget en))) 10)).... Even if you select _All -David Brilliant (foreach obj SS,,,, You cant use foreach on a pickset Cary (vla-put-layer obj Lay10) Need a vla-object + a valid layer Quote Link to comment Share on other sites More sharing options...
chulse Posted April 28, 2012 Author Share Posted April 28, 2012 Ok, so if I understand - we select all LWPOLYLINES, then filter out all the ones that are multiples of ten? How do we test for the z value being a multiple of 10 though? I don't understand how that is happening... Then, what's the best way to change the layer of the entities in the selection set? Thanks Quote Link to comment Share on other sites More sharing options...
chulse Posted April 28, 2012 Author Share Posted April 28, 2012 Brilliant You cant use foreach on a pickset Gary Need a vla-object + a valid layer So I need to convert the OBJ to a VLA-Object first then? Quote Link to comment Share on other sites More sharing options...
pBe Posted April 28, 2012 Share Posted April 28, 2012 (edited) Not necesarily...Tell us, after the layer thingy, what else do you need to do? If thats all there is to it. you dont need to create another selection set Building on Davids code (defun c:topten (/ en e ) (and (setq ss (ssget '((0 . "LWPOLYLINE")))) (while (setq en (ssname ss 0)) (if (zerop (rem (cdr (assoc 38 [color=blue][b](setq e[/b][/color] (entget en)))) 10)) [color=blue][b](entmod (subst (cons 8 [color=green]"E-TOPO-10")[/color][/b][/color] [b][color=blue] (assoc 8 e) e))[/color][/b] ) (ssdel en ss))) ) UPDATED Edited April 28, 2012 by pBe EDIT : CIVIL MODE Quote Link to comment Share on other sites More sharing options...
chulse Posted April 28, 2012 Author Share Posted April 28, 2012 that's all - the goal is to find all the index contours (multiples of 10) and set them on a specific layer. I will probably try to set all the remaining contours on a different layer also. these contours all come from imported GIS data and the sets can be huge, so doing this manually is all but impossible. this is what I have at the moment: (defun C:SCL (/ *error* msg ELEV SS LAY2 LAY10 DOC UFLAG ALL obj temp) ;layer name used for 10' contours (setq lay10 "E-TOPO-10") ;layer name used for 2' contours (setq lay2 "E-TOPO-2") (vl-load-com) (setq DOC (vla-get-ActiveDocument (vlax-get-acad-object))) ;; --{ Error Handler Function }-- (defun *error* (msg) (and uflag (vla-EndUndoMark doc)) (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*") (princ (strcat "\n** Error: " msg " **"))) (princ)) ;; --{ Main Function }-- (setq uflag (not (vla-StartUndoMark doc))) ;;; CHECK FOR LAYER AND ADD IF NOT EXIST (or (tblsearch "LAYER" LAY10) (vla-add (vla-get-layers doc) LAY10)) (or (tblsearch "LAYER" LAY2) (vla-add (vla-get-layers doc) LAY2)) ;put all obj on 2' contour layer (setq all (ssget "_X" '((0 . "LWPOLYLINE") ))) (foreach obj all (vla-put-layer obj LAY2) );_end foreach ;(find all contours from 10 to 10000 by 10) (setq elev 10 ss (ssadd)) (while (<= elev 10000);max elevation searched for is 10,000 feet - change if need be (if (setq temp (ssget "_X" (List '(0 . "LWPOLYLINE") (cons 38 elev)))) (repeat (setq i (sslength temp)) (ssadd (ssname temp (setq i (1- i))) ss))) (setq elev (+ elev 10)) );_end while ;put 10' contours on correct new layer (foreach obj SS (vla-put-layer obj Lay10) );_end foreach ;clear ss (setq ss nil) (setq all nil) (setq uFlag (vla-EndUndoMark doc)) (princ) );_end defun Quote Link to comment Share on other sites More sharing options...
David Bethel Posted April 28, 2012 Share Posted April 28, 2012 (if (zerop (rem (cdr (assoc 38 (entget en))) 10)) IF the remainder of dividing the LWPOLYLINE elevation (cdr (assoc 38 (entget en))) by 10 is zerop THEN add the ENAME to the PICKSET I'm still a command guy at heart: If the layer exists: (command "_.CHPROP" s1 "" "_LA" "layer_name" "") -David Quote Link to comment Share on other sites More sharing options...
pBe Posted April 28, 2012 Share Posted April 28, 2012 that's all - the goal is to find all the index contours (multiples of 10) and set them on a specific layer. I will probably try to set all the remaining contours on a different layer also. ;layer name used for 10' contours (setq lay10 "E-TOPO-10") ;layer name used for 2' contours (setq lay2 "E-TOPO-2") Oh man.. (strcat "Lay" (itoa (fix elv))) (strcat "E-TOPO-" (itoa (fix elv))) Kudos to David Quote Link to comment Share on other sites More sharing options...
chulse Posted April 28, 2012 Author Share Posted April 28, 2012 Thanks for the explanation. That makes perfect sense. 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.