Logical Operator "<NOT" Failing To Exclude Entity

Logical Operator "<NOT" Failing To Exclude Entity

walter_houghton
Participant Participant
1,733 Views
18 Replies
Message 1 of 19

Logical Operator "<NOT" Failing To Exclude Entity

walter_houghton
Participant
Participant

So I have been modifying an existing auto lisp that is meant to delete all revclouds in a drawing. However, it so happens to be the parameters set up in the lisp also select part of a logo in the title block. My work around was to add a "<NOT" "NOT>" logical operator into the ssget function. I tried Group code 10 to exclude the exact object based on the info pulled from the dxf data, but for some reason it still selects the polyline.  The Code is below. It runs and loads fine, but it runs as if the "NOT" logical operator isnt even there.

 

(defun c:REVCSEL (/ s e i a p)
(if (setq s (ssget "_X" '((0 . "LWPOLYLINE") (410 . "Model") (-4 . "/=") (42 . 0) (-4 . ">") (90 . 4) (-4 . "<NOT") (10 -516.149 553.471) (-4 . "NOT>"))))
(repeat (setq i (sslength s))
(setq e (ssname s (setq i (1- i)))
a (length (vl-remove-if-not '(lambda (u) (and (eq (car u) 42) (not (eq (cdr u) 0)))) (entget e)))
p (length (vl-remove-if-not '(lambda (u) (eq (car u) 10)) (entget e)))
)
(if (not (or (eq a p) (eq (1+ a) p)))
(ssdel e s)
)
)
)
(sssetfirst nil s)
(princ)
)

0 Likes
Accepted solutions (1)
1,734 Views
18 Replies
Replies (18)
Message 2 of 19

BlackBox_
Advisor
Advisor

You didn't post a sample drawing for us to test, but this is working here: 

(defun c:REVCSEL (/ s)
  (if
    (setq s
           (ssget "_X"
                  '((0 . "LWPOLYLINE")
                    (410 . "Model")
                    (-4 . ">")
                    (90 . 4)
                    (-4 . "/=")
                    (42 . 0)
                   )
           )
    )
     (sssetfirst nil s)
  )
  (princ)
)


"How we think determines what we do, and what we do determines what we get."

Sincpac C3D ~ Autodesk Exchange Apps

0 Likes
Message 3 of 19

walter_houghton
Participant
Participant

Sorry about that, here is a test drawing essentially, I want to exclude the two bottom right entities from the selection set

0 Likes
Message 4 of 19

vladimir_michl
Advisor
Advisor

You cannot use equal or non-equal conditions on real numbers pulled from some DXF or list - the internal representation of these real numbers differ on some (not pulled) decimal places. Use > and < , or window-selection instead.

 

Vladimir Michl, www.arkance.world  -  www.cadforum.cz

 

0 Likes
Message 5 of 19

walter_houghton
Participant
Participant

Sorry Im pretty new to this, but I tried looking up ways to use crossing and window selection, but I couldn't seem to find a way to deselect items from an already existing set through autolisp, is there a deselect function that can be set to affect object between two points?

0 Likes
Message 6 of 19

BlackBox_
Advisor
Advisor

@walter_houghton thanks for the sample drawing.

 

Based on that 2007 drawing, this works... Just  be sure to revise the points list for ssget, as needed:

 

(defun c:REVCSEL (/ HasAllNonZeroBulges ss i ssRevclouds e eData)

  (defun HasAllNonZeroBulges (eData / allNonZeroBulges)
    (setq allNonZeroBulges T)
    (foreach item eData
      (if (and allNonZeroBulges
               (= 42 (car item))
          )
        (if (< 0.0 (abs (cdr item)))
          T
          (setq allNonZeroBulges nil)
        )
      )
    )
    allNonZeroBulges
  )
  
  (if
    (and
      (= "Model" (getvar 'ctab))
      (setq ss
             (ssget "_CP"
                    '((-2506.39 1989.13)
                      (-3371.93 261.312)
                      (-1275.05 266.462)
                      (-285.854 917.935)
                     )
             )
      )
    )
     (progn
       (setq i 0)
       (setq ssRevclouds(ssadd))
       (repeat (sslength ss)
         (if
           (and
             (setq e (ssname ss i))
             (< 4 (cdr (assoc 90 (setq eData (entget e)))))
             ;;(< 0 (abs (cdr (assoc 42 eData)))) ; this only gets first dxf 42
             (HasAllNonZeroBulges eData) ; need to check all segments
           )
            (ssadd e ssRevclouds)
         )
         (setq i (1+ i))
       )
       (if (< 0 (setq i (sslength ssRevclouds)))
         (sssetfirst nil ssRevclouds)
       )
     )
  )
  (prompt
    (strcat "\n"
            (itoa i)
            " Revcloud"
            (if (= 1 i)
              ""
              "s"
            )
            " selected. \n"
    )
  )
  (princ)
)

 

[Edit] - The code has been revised to account for all polyline segments, polylines with all bulges are considered Revclouds.


"How we think determines what we do, and what we do determines what we get."

Sincpac C3D ~ Autodesk Exchange Apps

0 Likes
Message 7 of 19

Kent1Cooper
Consultant
Consultant
Accepted solution

(10 -516.149 553.471)

I think that would work only if those coordinates apply to the first vertex.  Is that the case?

But I assume the problem could, at least in part, that those values are rounded, and the real coordinates are, for example:

(10 -516.148732 553.471376)

The (ssget) filter is going to need precise agreement.

Kent Cooper, AIA
0 Likes
Message 8 of 19

komondormrex
Mentor
Mentor

try to ssget all revclouds via extended data

(ssget "_x" '((0 . "lwpolyline") (410 . "Model") (-3 ("RevcloudProps"))))

 

0 Likes
Message 9 of 19

BlackBox_
Advisor
Advisor

@komondormrex wrote:

try to ssget all revclouds via extended data

(ssget "_x" '((0 . "lwpolyline") (410 . "Model") (-3 ("RevcloudProps"))))

 


 

@komondormrex  - I did same initially, until I realized: 

 

(defun c:HeresWhyThatWontWork (/ n ss)

  ;; create a revcloud
  (setq n 0.25)
  (if (= "Model" (getvar 'ctab))
    (setq n (* (/ 1. (getvar 'cannoscalevalue)) 0.25))
  )
  (command-s "._revcloud" "_s" "_c" "_a" n (* 2. n) "_o")
  (while (= 1 (getvar 'cmdactive))
    (command pause)
  )

  ;; now try to select it
  (if (setq ss
             (ssget
               "_x"
               '((0 . "lwpolyline") (410 . "Model") (-3 ("RevcloudProps")))
             )
      )
    (sssetfirst nil ss)
    (prompt "\n** No valid Revclouds found ** ")
  )
  
  (princ)
)

 

Autodesk has a bug in the REVCLOUD Command, as otherwise valid Revclouds are created (per properties pane), but the "RevcloudProps" XData isn't being appended.

 

Also, Autodesk didn't implement this "RevcloudProps" XData until 2021 version, so this won't work for anyone using older than that. User posted a 2007 format sample DWG, so I skipped this option. 

 

Cheers

 

[Edit] - has been reported to Autodesk as BUG:3549

 


"How we think determines what we do, and what we do determines what we get."

Sincpac C3D ~ Autodesk Exchange Apps

0 Likes
Message 10 of 19

komondormrex
Mentor
Mentor

i checked this on the user file, all 7 revclouds get xd appended.

0 Likes
Message 11 of 19

BlackBox_
Advisor
Advisor

@komondormrex wrote:

i checked this on the user file, all 7 revclouds get xd appended.


As did I... Please test the code in my replies.

 

Your code - same as my initial code, no judgment - does not work on Revclouds created by Object, where the code here works on both.

 

Cheers


"How we think determines what we do, and what we do determines what we get."

Sincpac C3D ~ Autodesk Exchange Apps

0 Likes
Message 12 of 19

komondormrex
Mentor
Mentor

@BlackBox_ wrote:

code here works on both.


sorry to dissapoint you, but it doesn't. see the screenshots attached. 

 

0 Likes
Message 13 of 19

BlackBox_
Advisor
Advisor

@komondormrex wrote:

@BlackBox_ wrote:

code here works on both.


sorry to dissapoint you, but it doesn't. see the screenshots attached. 

 


Thank you, my friend - you frequently post code that helps others - I simply wanted you to know that we agree, that your method should work, and be 100% trustworthy (in 2021+), but  it does not work at all on Revclouds created by Object (through no fault of your own). 

 

In 2021 Autodesk failed to properly implement a new Revcloud type when granting that feature request - they instead opted to instantiate an object overrule, as evidenced by the Revcloud's entity data's still listing DXF 0 == "LWPOLYLINE" and/or  ObjectName == "AcDbPolyline". Autodesk failed to append the "RevcloudProps" XData during the 'by Object' portion of the CommandMethod, my guess is that the SwapIdWith() call made after creating the new Revcloud and before deleting the original Polyline has something to do with it. Regardless, this is a bug and has been reported to the AutoCAD team already. 

 

Not disappointed at all. Your images memorialize that the code in post 6 correctly selects any Polyline comprised of all bulge segments (commonly a Revcloud, even pre-2021, not always, obviously), and that you had to copy parts of the logo up among the Revclouds that my code didn't collect (on purpose, per the OP's request). 

 

Your images also confirm that you didn't try the code in post 9 (at least for those images, that is), as that code would have created a Revcloud by Object (listed as Revcloud in properties pane, not Polyline) and only selected those that had "RevcloudProps" XData (which Revclouds created by Object do not). 

 

Thanks for your time and consideration! 

 

Cheers

 


"How we think determines what we do, and what we do determines what we get."

Sincpac C3D ~ Autodesk Exchange Apps

0 Likes
Message 14 of 19

walter_houghton
Participant
Participant

Is there a way to get a more precise coordinate value currently im using 

(entget (car (entsel)))

or do I have to mess with my precision settings to get an exact value?

0 Likes
Message 15 of 19

walter_houghton
Participant
Participant

I figured out how to increase the precision for the coord data, thank you! This is how my lisp turned out in the end.

(defun c:REVCSEL (/ s e i a p)
 (if (setq s (ssget "_X" '((0 . "LWPOLYLINE") (410 . "Model") (-4 . "/=") (42 . 0) (-4 . ">") (90 . 4) 
    (-4 . "<NOT") (10 -516.14923929 553.47129249) (-4 . "NOT>")(-4 . "<NOT") (10 -515.46212552 553.44825090) (-4 . "NOT>"))))
   (repeat (setq i (sslength s))
     (setq e (ssname s (setq i (1- i)))
           a (length (vl-remove-if-not '(lambda (u) (and (eq (car u) 42) (not (eq (cdr u) 0)))) (entget e)))
           p (length (vl-remove-if-not '(lambda (u) (eq (car u) 10)) (entget e)))
     )
     (if (not (or (eq a p) (eq (1+ a) p)))
       (ssdel e s)
     )
   )
 )
 (sssetfirst nil s)
 (princ)
)
0 Likes
Message 16 of 19

Kent1Cooper
Consultant
Consultant

@walter_houghton wrote:

Is there a way to get a more precise coordinate value ...?


[You posted while I was writing this, but anyway....]

If you are always actually picking the Polyline you want it to not select, maybe taking its entity data entry directly [instead of pulling the coordinates away from the 10 DXF-code number than recombining them with a 10 again] would work:

(if (setq s (ssget "_X"
  (list
  '(0 . "LWPOLYLINE") '(410 . "Model") '(-4 . "/=") '(42 . 0) '(-4 . ">")
  '(90 . 4) '(-4 . "<NOT") (assoc 10 edata) '(-4 . "NOT>"))))

But if you're actually picking it, it would be simpler to let the routine find it along with the ones you want, and then use (ssdel) to remove that one from the set.

But there's still the issue of which 10 entry it will see.

Or, filter to exclude the Layer it's on, or by some other characteristic, rather than a vertex location.

Kent Cooper, AIA
0 Likes
Message 17 of 19

komondormrex
Mentor
Mentor

you frequently post code that helps others
wow, you are the one other than applicants, who said that in words. thank you.

 

that your method should work
you know, it's not MY method, it's just slightly deeper than basic usage of autolisp. everyone who ever touched xd might be as well aware of it.

 

it does not work at all on Revclouds created by Object
that is a very wierd thing and since a revloud is a pline in its nature it is pretty hard to sort one of other. i think that is solvable via writing a custom lisp-command to convert an object to a revcloud to have xd. 

 

Your images also confirm that you didn't try the code in post 9 (at least for those images, that is)
on the contrary, i actually did, and let you be assured, it amazed me a lot) i mean a revcloud without xd appended.

0 Likes
Message 18 of 19

BlackBox_
Advisor
Advisor

@komondormrex wrote:

you frequently post code that helps others
wow, you are the one other than applicants, who said that in words. thank you.


Most welcome! It's a bit too early for :beer:, so :IrishCoffee: Haha

 


@komondormrex wrote:

that your method should work
you know, it's not MY method, it's just slightly deeper than basic usage of autolisp. everyone who ever touched xd might be as well aware of it.


You're obviously correct; what I intended was to pay attribution, as you'd posted it first. While I included same in my initial attempt, I tested it on one of my own drawings too (sometimes a DWG sysvar changes things, etc) and noticed it didn't work, even though my LISP Defun uses REVCLOUD Command with Object selection. Only then did I research it a bit and discovered that the XData wasn't implemented until 2021, so when I noticed the OP's sample DWG was 2007 format, I assumed it wouldn't work in all cases or versions. That's what led to my earlier post. 

 


@komondormrex wrote:

it does not work at all on Revclouds created by Object
that is a very wierd thing and since a revloud is a pline in its nature it is pretty hard to sort one of other. i think that is solvable via writing a custom lisp-command to convert an object to a revcloud to have xd. 


Agreed! For our internal standards Revclouds are on a specific layer, which makes this a bit easier to do. To automate it for our users, I was going to use .NET to provide an Object Overrule that automagically applies the XData when using native REVCLOUD Command, so users never even notice and anyone they send our drawings to will benefit (if they use SSGET as you'd posted). 

 

Here's one example of what an Object Overrule can do: https://apps.autodesk.com/ACD/en/Detail/Index?id=8292913608752806337&appLang=en&os=Win32_64

 


@komondormrex wrote:

Your images also confirm that you didn't try the code in post 9 (at least for those images, that is)
on the contrary, i actually did, and let you be assured, it amazed me a lot) i mean a revcloud without xd appended.


Mea culpa for the assumption. That's kind of you to say, thank you!  

 

Cheers


"How we think determines what we do, and what we do determines what we get."

Sincpac C3D ~ Autodesk Exchange Apps

0 Likes
Message 19 of 19

BlackBox_
Advisor
Advisor

@Kent1Cooper wrote:

@walter_houghton wrote:

Is there a way to get a more precise coordinate value ...?


[You posted while I was writing this, but anyway....]

If you are always actually picking the Polyline you want it to not select, maybe taking its entity data entry directly [instead of pulling the coordinates away from the 10 DXF-code number than recombining them with a 10 again] would work:

(if (setq s (ssget "_X"
  (list
  '(0 . "LWPOLYLINE") '(410 . "Model") '(-4 . "/=") '(42 . 0) '(-4 . ">")
  '(90 . 4) '(-4 . "<NOT") (assoc 10 edata) '(-4 . "NOT>"))))

But if you're actually picking it, it would be simpler to let the routine find it along with the ones you want, and then use (ssdel) to remove that one from the set.

But there's still the issue of which 10 entry it will see.

Or, filter to exclude the Layer it's on, or by some other characteristic, rather than a vertex location.


@Kent1Cooper is correct; I ran into this same issue in post 6 above, when checking DXF 42 for non-zero bulge. 

 

I had to edit my post when I realized I was only checking the first DXF 42, then revised it to iterate all DXF 42 entries... if 1 or more were zero, then the code logic assumed a Polyline, if all were non-zero it assumed a Revcloud. 


"How we think determines what we do, and what we do determines what we get."

Sincpac C3D ~ Autodesk Exchange Apps

0 Likes