Does anyone know a way (via quickselect or others) to choose all polylines which have an elevation that ends in zero(i.e. index contours 980,990 etc..). It has been about ten years since I have done any Autolisp coding so I hope it is built in functionality that I am missing.
I am using Land Desktop 09 but it might be functionality in numerous products.
Thanks
spice70
@Anonymous wrote:Does anyone know a way (via quickselect or others) to choose all polylines which have an elevation that ends in zero(i.e. index contours 980,990 etc..). It has been about ten years since I have done any Autolisp coding so I hope it is built in functionality that I am missing.
I am using Land Desktop 09 but it might be functionality in numerous products.
Thanks
spice70
You mean all polylines that are parallel to WCS and have elevation 980,990 etc...?
Or you mean that ending vertex have elevation Z coordinate = 0.0...?
By polylines, do you mean 2d polylines, or both 2d and 3d polylines...?
If you mean only 2d polylines that are parallel to WCS try this :
(sssetfirst nil (ssget "_X" '((0 . "*POLYLINE") (-4 . "&=") (70 . 0) (-4 . "<or") (210 0.0 0.0 1.0) (210 0.0 0.0 -1.0) (-4 . "or>"))))
I work with 2D polylines with Z. In other words it is a polyline where all verticies have an elevation equal to 980.
Hello Marko,
Thank you for the help thus far. The command you gave picked all of the polylines in the drawing. I need a function that would return lines whose elevation divided by 10 (/10) would leave a remainder of zero. Similar to the Mod function I've used in several programming languages. The command line you sent has far extended my understanding as I am just starting to get back into autoCAD with my new job. The last time I used AutoCAD regularly and did any Lisp writing was when V14 was the current release. Be gentle... and thanks again.
@Anonymous wrote:Hello Marko,
Thank you for the help thus far. The command you gave picked all of the polylines in the drawing. I need a function that would return lines whose elevation divided by 10 (/10) would leave a remainder of zero. Similar to the Mod function I've used in several programming languages. The command line you sent has far extended my understanding as I am just starting to get back into autoCAD with my new job. The last time I used AutoCAD regularly and did any Lisp writing was when V14 was the current release. Be gentle... and thanks again.
(defun c:selplselevsby10 ( / ss sss ) (vl-load-com) (setq sss (ssadd)) (setq ss (ssget "_X" '((0 . "*POLYLINE") (-4 . "&=") (70 . 0) (-4 . "<or") (210 0.0 0.0 1.0) (210 0.0 0.0 -1.0) (-4 . "or>")))) (vlax-for pl (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))) (if (eq (rem (vla-get-elevation pl) 10.0) 0.0) (ssadd (vlax-vla-object->ename pl) sss) ) ) (sssetfirst nil sss) (princ) ) (defun c:spls nil (c:selplselevsby10)) (prompt "\nInvoke with : spls") (princ)
I might try this another way... I have been searching through the Lisp functions and still can't seem to find what I am looking for. I will try to describe via code as though in plain English.
If the remainder of polyline's (elevation/10) = 0
then select polyline
ie 980 = true
982 = false
886 = false
985 = false
1000 = true
Marko,
I will have to try this command when I get back to the office. With my limited ability to decipher the more recent code I did notice the REM function which will be the key to me solving this. Thank you again for all of your help and I will post again after trying this at work.
Thanks,
spice70
(defun c:Test (/ ss i e d n z) (if (setq ss (ssget "_X" '((0 . "*POLYLINE") (-4 . "&=") (70 . 0) (-4 . "<or") (210 0.0 0.0 1.0) (210 0.0 0.0 -1.0) (-4 . "or>") ) ) ) (progn (repeat (setq i (sslength ss)) (setq e (ssname ss (setq i (1- i))) d (entget e) n (cdr (assoc 100 (cdr (member (assoc 100 d) d)))) ) (if (or (not (setq z (cond ((eq n "AcDb2dPolyline") (last (assoc 10 d))) ((eq n "AcDbPolyline") (cdr (assoc 38 d))) ) ) ) (/= (rem z 10.) 0.) ) (setq ss (ssdel e ss)) ) ) (sssetfirst nil ss) ) ) (princ) )
Hi,
I got this lisp at some point, I believe through this forum. It isn't exactly what you describe but I have found it useful. It will delete contours that do not fall in to the elevation devider set. (open the lisp to edit this to suit your selection requirements)
I hope it helps
Regards
Sean
;this lisp will find plines with elevation and erase them.
;Value marked XXX can be changed to alter selection set erased
(defun c:elevpk (/ ss1 ss2 sslen)
(setq ss1 (ssget '((0 . "*line")))
ss2 (ssadd)
sslen (sslength ss1)
cnt 0
)
(repeat sslen
(setq en (ssname ss1 cnt)
ed (entget en)
ed38 (cdr (assoc 38 ed))
remed38 (rem ed38 2.5);XXXthis 2.5 value means all but .0 and .5 value contours will be deleted.
)
(if
(> remed38 0.0)
(ssadd en ss2)
) ;if
(setq cnt (1+ cnt))
) ;repeat
(command "erase" ss2 "")
(prompt (strcat "\n"
(rtos (sslength ss2) 2 0)
" unwanted contours have been removed"
)
)
(princ)
) ;defun
;|«Visual LISP© Format Options»
(72 2 40 1 nil "end of " 60 9 0 0 0 T T nil T)
;*** DO NOT add text below the comment! ***|;
@marko_ribar wrote:If you mean only 2d polylines that are parallel to WCS try this :
(sssetfirst nil (ssget "_X" '((0 . "*POLYLINE") (-4 . "&=") (70 . 0) (-4 . "<or") (210 0.0 0.0 1.0) (210 0.0 0.0 -1.0) (-4 . "or>"))))
That (70 . 0) won't find closed Polylines [for which the 70 value includes the 1 bit], nor those for which linetype generation is enabled [the 128 bit], either of which seem like common enough characteristics of contour lines, nor one that is perhaps less common: "heavy" 2D Polylines which have been fit- [the 2 bit] or spline- [the 4 bit] curved. [Also true of the routines in Messages 6 & 9].
Please try attached ELEVLAYER.vlx, which puts objects into different layers based on their elevations.
Following steps below to select objects with certain elevations.
1. Change objects layer with ELEVLAYER. It will create layers named as ELEV-0, ELEV-980, ELEV-982, ELEV-1000, etc and put objects to the layer it belongs to.
2. In the Layer Manager, set up a layer with Filter Name "EEE". In the Filter Definition, set its "NAME" column to "ELEV-*0". So all layers names ends at 0 are included.
3. Click "All" in layer Filters column and turn all layers off (confirm turn off current layer).
4. Click "EEE" in layer Filters column and turn on all layers in this filter.
Now you can easily select the objects on desired elevations.
By the way, if the purpose is to set a special color to these objects on "Main Contour", you just get into the layer filter after Step 2 and change the layer colors.
@Kent1Cooper wrote:
@marko_ribar wrote:If you mean only 2d polylines that are parallel to WCS try this :
(sssetfirst nil (ssget "_X" '((0 . "*POLYLINE") (-4 . "&=") (70 . 0) (-4 . "<or") (210 0.0 0.0 1.0) (210 0.0 0.0 -1.0) (-4 . "or>"))))
That (70 . 0) won't find closed Polylines [for which the 70 value includes the 1 bit], nor those for which linetype generation is enabled [the 128 bit], either of which seem like common enough characteristics of contour lines, nor one that is perhaps less common: "heavy" 2D Polylines which have been fit- [the 2 bit] or spline- [the 4 bit] curved. [Also true of the routines in Messages 6 & 9].
My mistake, in part -- I didn't catch the (-4 . "&=") in there. I don't quite get how that's supposed to work from the description in the Developer's Guide, and haven't been able to find other examples of its use [even searching for "&=" in this forum doesn't find this thread!], but the function does find at least some of those types I thought it wouldn't. However, there's still something not quite right about it, because it also finds and highlights 3DPolylines that are not parallel to the WCS XY plane, and even those that are not planar and therefore not in or parallel to any plane.
Kent, this may be of use:
=================================================================================================== SSGET =================================================================================================== (ssget [sel-method] [pt1 [pt2]] [pt-list] [filter-list]) =================================================================================================== Visual LISP IDE Help Documentation Relevant Sections: --------------------------------------------------------------------------------------------------- +-- AutoLISP Developer's Guide | +--+-- Using the AutoLISP Language | +--+-- Using AutoLISP to Manipulate AutoCAD Objects | +--+-- Selection Set Handling | +--+-->> Selection Set Filter Lists | +-->> Wild-Card Patterns in Filter Lists | +-->> Filtering for Extended Data | +-->> Relational Tests | +-->> Logical Grouping of Filter Tests | +-->> Selection Set Manipulation +-- AutoLISP Reference | +--+-- AutoLISP Functions | +--+-- S Functions | +--+-->> ssget =================================================================================================== Mode Strings --------------------------------------------------------------------------------------------------- +. Point Selection Mode The undocumented "+." mode forces (ssget) to remain in "point" mode, similar to setting PickAuto to 0. It helps the ":S" single-selection mode and ":E" mode act just like (entsel) by avoiding implied selection windows. --------------------------------------------------------------------------------------------------- A All Like "X" but filters frozen out. Selects all objects on thawed layers. --------------------------------------------------------------------------------------------------- B Box Selects all objects inside or crossing a rectangle specified by two points. If the rectangle's points are specified from right to left, Box is equivalent to Crossing. Otherwise, Box is equivalent to Window. --------------------------------------------------------------------------------------------------- C Crossing Selects objects within and crossing an area defined by two points. A crossing selection is displayed as dashed or otherwise highlighted to differentiate it from window selection. (ssget "_C" '(0 0) '(1 1)) Points in UCS ** Caution: the selection area must be visible on screen for this to work properly ** (command "._zoom" "_E") --------------------------------------------------------------------------------------------------- CP Crossing Polygon Selects objects within and crossing a polygon defined by specified points. The polygon can be any shape but cannot cross or touch itself. AutoCAD draws the last segment of the polygon so that it is closed at all times. CP is not affected by the PICKADD System Variable. (ssget "_CP" '((1 1) (3 1) (5 2) (2 4))) Points in UCS Example with filters: (ssget "_CP" '<Point list> '<Filter List>) (ssget "_CP" '((0 0) (10 0) (10 10) (0 10)) '((0 . "INSERT") (66 . 1))) ** Caution: the selection area must be visible on screen for this to work properly ** (command "._zoom" "_E") --------------------------------------------------------------------------------------------------- :D Allow Duplicates Includes duplicates in the selection, else duplicates are ignored --------------------------------------------------------------------------------------------------- :E Everything in aperture Allows selection of everything within the cursor's object selection pickbox. --------------------------------------------------------------------------------------------------- F Fence Selects all objects crossing a selection fence. The Fence method is similar to CPolygon except that AutoCAD does not close the fence, and a fence can cross itself. Fence is not affected by the PICKADD System Variable. --------------------------------------------------------------------------------------------------- G Groups Selects all objects within a specified group. --------------------------------------------------------------------------------------------------- I Implied Implied selection (objects selected while PICKFIRST is in effect). --------------------------------------------------------------------------------------------------- L Last Selects the last visible object added to the drawing database --------------------------------------------------------------------------------------------------- :L Rejects objects on locked layers --------------------------------------------------------------------------------------------------- M Multiple Specifies multiple points without highlighting the objects, thus speeding up the selection process for complex objects. The Multiple method also selects two intersecting objects if the intersection point is specified twice. --------------------------------------------------------------------------------------------------- :N Nested Call ssnamex for additional information on container blocks and transformation matrices for any entities selected during the ssget operation. This additional information is available only for entities selected via graphical selection methods such as Window, Crossing, and point picks. Unlike the other object selection methods, :N may return multiple entities with the same entity name in the selection set. For example, if the user selects a subentity of a complex entity such as a BlockReference, PolygonMesh, or old style polyline, ssget looks at the subentity that is selected when determining if it has already been selected. However, ssget actually adds the main entity (BlockReference, PolygonMesh, etc.) to the selection set. The result could be multiple entries with the same entity name in the selection set (each will have different subentity information for ssnamex to report). --------------------------------------------------------------------------------------------------- P Previous Selects the most recent selection set. The Previous selection set is cleared by operations that delete objects from the drawing. AutoCAD keeps track of whether each selection set was specified in model space or paper space. The Previous selection set is ignored if you switch spaces. --------------------------------------------------------------------------------------------------- :P Rejects Viewports --------------------------------------------------------------------------------------------------- :R Allows entities in a long transaction to be selected. --------------------------------------------------------------------------------------------------- :S Force single selection. The user is permitted a single attempt to make a selection of objects using any available selection method. When combined with either "+." or ":E", only a single object may be selected. --------------------------------------------------------------------------------------------------- :U Enables subentity selection - 2006+ Cannot be combined with the duplicate (":D") or nested (":N") selection modes. In this mode, top-level entities are selected by default, but the user can attempt to select subentities by pressing the CTRL key while making the selection. This option is supported only with interactive selections, such as window, crossing, and polygon. It is not supported for all, filtered, or group selections. --------------------------------------------------------------------------------------------------- :V Forces subentity selection - 2006+ Treats all interactive, graphic selections performed by the user as subentity selections. The returned selection set contains subentities only. This option cannot be combined with the duplicate (":D") or nested (":N") selection modes. This option is supported only with interactive selections, such as window and crossing. It is not supported for all, filtered, or group selections. --------------------------------------------------------------------------------------------------- W Window Selects all objects completely inside a rectangle defined by two points. Specifying the corners from left to right creates a window selection. (Specifying the corners from right to left creates a crossing selection.) --------------------------------------------------------------------------------------------------- WP Window Polygon Selects objects completely inside a polygon defined by points. The polygon can be any shape but cannot cross or touch itself. AutoCAD draws the last segment of the polygon so that it is closed at all times. WPolygon is not affected by the PICKADD System Variable. ** Caution: the selection area must be visible on screen for this to work properly ** (command "._zoom" "_E") --------------------------------------------------------------------------------------------------- X Extended search (search whole drawing database) Entire database. If you specify the X selection method and do not provide a filter-list, ssget selects all entities in the database, including entities on layers that are off, frozen, and out of the visible screen. =================================================================================================== System Variables --------------------------------------------------------------------------------------------------- PICKADD Controls whether subsequent selections replace the current selection set or add to it. 0 Turns off PICKADD. The objects and subobjects most recently selected become the selection set. Previously selected objects and subobjects are removed from the selection set. Add more objects or subobjects to the selection set by pressing SHIFT while selecting. 1 Turns on PICKADD. Each object and subobject selected, either individually or by windowing, is added to the current selection set. To remove objects or subobjects from the set, press SHIFT while selecting. --------------------------------------------------------------------------------------------------- PICKAUTO Controls automatic windowing at the Select Objects prompt. 0 Turns off PICKAUTO 1 Draws a selection window (for either a window or a crossing selection) automatically at the Select Objects prompt --------------------------------------------------------------------------------------------------- PICKDRAG Controls the method of drawing a selection window. 0 Draws the selection window using two points. Click the pointing device at one corner, and then click to select another corner. 1 Draws the selection window using dragging. Click one corner and drag the pointing device, release the button at the other corner. --------------------------------------------------------------------------------------------------- PICKFIRST Controls whether you select objects before (noun-verb selection) or after you issue a command. 0 Turns off PICKFIRST, you select objects after you issue a command 1 Turns on PICKFIRST, you select objects before you issue a command --------------------------------------------------------------------------------------------------- PICKSTYLE Controls the use of group selection and associative hatch selection. 0 No group selection or associative hatch selection 1 Group selection 2 Associative hatch selection 3 Group selection and associative hatch selection =================================================================================================== -4 Relational Filter Codes --------------------------------------------------------------------------------------------------- Notes: For point groups, the X, Y, and Z tests can be combined into a single string, with each operator separated by commas (for example, ">,>,*"). If an operator is omitted from the string (for example, "=,<>" leaves out the Z test), then the 'anything goes' operator, "*", is assumed. Direction vectors (DXF Group code 210) can be compared only with the operators "*", "=", and "!=" (or one of the equivalent 'not equal' strings). --------------------------------------------------------------------------------------------------- "*" Anything goes (always true) --------------------------------------------------------------------------------------------------- "=" Equals --------------------------------------------------------------------------------------------------- "!=" Not equal to --------------------------------------------------------------------------------------------------- "/=" Not equal to --------------------------------------------------------------------------------------------------- "<>" Not equal to --------------------------------------------------------------------------------------------------- "<" Less than --------------------------------------------------------------------------------------------------- "<=" Less than or equal to --------------------------------------------------------------------------------------------------- ">" Greater than --------------------------------------------------------------------------------------------------- ">=" Greater than or equal to --------------------------------------------------------------------------------------------------- "&" Bitwise AND (integer groups only) Equivalent to: (/= 0 (logand bit filter)) --------------------------------------------------------------------------------------------------- "&=" Bitwise masked equals (integer groups only) Equivalent to: (= filter (logand bit filter)) =================================================================================================== -4 Logical Filter Codes --------------------------------------------------------------------------------------------------- "<AND" One or more operands "AND>" --------------------------------------------------------------------------------------------------- "<OR" One or more operands "OR>" --------------------------------------------------------------------------------------------------- "<XOR" Two operands "XOR>" --------------------------------------------------------------------------------------------------- "<NOT" One operand "NOT>" ===================================================================================================
@alanjt_ wrote:Kent, this may be of use:
....
Thanks, but that's all "old news." However, I'll take advantage of the chance to ask for some explanation, if anyone can provide it. What I'm having trouble figuring out is specifically the "&=" relational test, at least as used in some routines on this thread. That is described in part of what you attached, which I had already pondered in the Developer's Guide:
"&=" Bitwise masked equals (integer groups only)
Equivalent to: (= filter (logand bit filter))
They don't give any examples of its usage or syntax, and it's not at all clear to me what the relationship is between the concepts of "mask" and "filter," or whether maybe they're really the same idea, though if they are, I am puzzled at their using both terms.
So in the relevant part of routines on this thread, there's this:
(-4 . "&=") (70 . 0)
I think I understand that if, for example, you wanted to find only closed Polylines, you would "mask" or "filter" for the 1 bit that is part of the DXF 70 value if a Polyline is closed, and would use:
(-4 . "&=") (70 . 1)
and I did eventually find something that did that on-line. It would seem that the 1 in that must be represented by "filter" in the description, and the (cdr (assoc 70 edata)) value in a Polyline's entity data list must be represented by "bit." Then, whether the latter is 1 or 9 or 129 or whatever, substituting them into the description gives:
(= 1 (logand (cdr (assoc 70 edata)) 1))
which would be True for any closed Polyline. Similarly, if you wanted to find only 3DPolylines, which have the 8 bit included in their DXF 70 value, you would use:
(-4 . "&=") (70 . 8)
So my main question is, what does it mean to use 0 there? Converting to the equivalency terms in the description, it would seem to be checking whether this is True for a given Polyline before admitting it to the selection set:
(= 0 (logand (cdr (assoc 70 edata)) 0))
But that doesn't accomplish anything I can figure out, because
(= 0 (logand any-integer-at-all 0))
always returns True! So it seems to be checking nothing more than whether or not there's a DXF 70 entry in the entity data at all, because only if there isn't one will it return nil. That check is therefore redundant, as far as I can tell, since (ssget) is already filtering for "*POLYLINE" entity types, and all varieties of those have a DXF 70 entry, and no matter what value that holds, it will pass the test.
I think that's why the code lets in some things that it shouldn't -- non-parallel-to-the-XY-plane and even non-planar 3DPolylines.
So what does
(-4 . "&=") (70 . 0)
actually accomplish? Am I missing something? Any further clarification would be most welcome.
I don't know, I thought it will mask (70 . 0) and (70 . 1), but not (70 . 😎 which was 3dpoly...
So I suppose this is unavoidable...
(defun c:selplselevsby10 ( / ss sss ) (vl-load-com) (setq sss (ssadd)) (setq ss (ssget "_X" '((0 . "*POLYLINE") (-4 . "<or") (70 . 0) (70 . 1) (-4 . "or>") (-4 . "<or") (210 0.0 0.0 1.0) (210 0.0 0.0 -1.0) (-4 . "or>")))) (vlax-for pl (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))) (if (eq (rem (vla-get-elevation pl) 10.0) 0.0) (ssadd (vlax-vla-object->ename pl) sss) ) ) (sssetfirst nil sss) (princ) ) (defun c:spls nil (c:selplselevsby10)) (prompt "\nInvoke with : spls") (princ)
How about this?
(defun c:Test (/ ss i e d n) (if (setq ss (ssget "_A" '((0 . "*POLYLINE") (-4 . "<NOT") (70 . 8) (-4 . "NOT>") (-4 . "<OR") (210 0.0 0.0 1.0) (210 0.0 0.0 -1.0) (-4 . "OR>") ) ) ) (progn (repeat (setq i (sslength ss)) (setq e (ssname ss (setq i (1- i))) d (entget e) n (cdr (assoc 100 (cdr (member (assoc 100 d) d)))) ) (if (/= (rem (cond ((eq n "AcDb2dPolyline") (last (assoc 10 d))) ((eq n "AcDbPolyline") (cdr (assoc 38 d))) ) 10. ) 0. ) (setq ss (ssdel e ss)) ) ) (sssetfirst nil ss) ) ) (princ) )
@alanjt_ wrote:How about this?
(defun c:Test (/ ss i e d n) (if (setq ss (ssget "_A" '((0 . "*POLYLINE") (-4 . "<NOT") (70 . 8) (-4 . "NOT>") (-4 . "<OR") (210 0.0 0.0 1.0) (210 0.0 0.0 -1.0) (-4 . "OR>") ) ) ) (progn (repeat (setq i (sslength ss)) (setq e (ssname ss (setq i (1- i))) d (entget e) n (cdr (assoc 100 (cdr (member (assoc 100 d) d)))) ) (if (/= (rem (cond ((eq n "AcDb2dPolyline") (last (assoc 10 d))) ((eq n "AcDbPolyline") (cdr (assoc 38 d))) ) 10. ) 0. ) (setq ss (ssdel e ss)) ) ) (sssetfirst nil ss) ) ) (princ) )
This will select also closed 3dpolylines and therefore routine will fail... Instead you probably wanted :
(if (setq ss (ssget "_A" '((0 . "*POLYLINE") (-4 . "<NOT") (-4 . "&=") (70 . 8) (-4 . "NOT>") (-4 . "<OR") (210 0.0 0.0 1.0) (210 0.0 0.0 -1.0) (-4 . "OR>") ) ) )
@marko_ribar wrote:I don't know, I thought it will mask (70 . 0) and (70 . 1), but not (70 . 😎 which was 3dpoly...
So I suppose this is unavoidable...
.... (setq ss (ssget "_X" '((0 . "*POLYLINE") (-4 . "<or") (70 . 0) (70 . 1) (-4 . "or>") (-4 . "<or") (210 0.0 0.0 1.0) (210 0.0 0.0 -1.0) (-4 . "or>")))) ....
That would then have one of the problems I first erroneously mentioned, that it would exclude Polylines with linetype generation enabled [128 bit]. One could let in LW & 2D Polylines that might or might not be closed and/or might or might not have linetype generation enabled, by adding more possibilities inside that OR grouping -- entries for 0, 1, 128 & 129. That's not too onerous, but if it's necessary to allow for Fit- or Spline-curved 2DPolylines [2 & 4 bits], a lot more possible combination values would be needed. I don't think the "&=" relational test can check for something not being there [the 8 bit to exclude 3DPolylines (but see below), and the 16/32/64 bits about Polyface Meshes], but maybe there's a way to do that.
Then there's also the question of whether they would want to include even 3DPolylines, if they are planar and parallel to the WCS X-Y plane.
It may be simpler to omit that particular narrowing-down within the (ssget) filtering, just grab all *Polylines with appropriate extrusion directions, then step through the selection and take out any that don't fit other criteria. 3DPolylines can be checked for planarity [is that a word?] with the (vlax-curve-isPlanar) function, Meshes can be eliminated by their second DXF 100 entry, etc.