Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: sel sets subfunctions

  1. #1
    All AUGI, all the time
    Join Date
    2015-10
    Location
    Belgrade, Serbia, Europe
    Posts
    564
    Login to Give a bone
    0

    Default sel sets subfunctions

    Hi all, I thought I should share these my sel sets subfunctions (as a matter a fact one of these (ss=ss1+ss2) has shown to be very useful in my last post...
    To cut off the story, here they are :
    Code:
    (defun ss=ss1+ss2 ( ss1 ss2 / lst1 n1 lst2 n2 lst n ss )
      (setq n1 (if (vl-catch-all-error-p (vl-catch-all-apply 'sslength (list ss1))) 0 (sslength ss1)))
      (repeat n1
        (setq lst1 (cons (ssname ss1 (setq n1 (1- n1))) lst1))
      )
      (setq n2 (if (vl-catch-all-error-p (vl-catch-all-apply 'sslength (list ss2))) 0 (sslength ss2)))
      (repeat n2
        (setq lst2 (cons (ssname ss2 (setq n2 (1- n2))) lst2))
      )
      (if (eq lst1 nil) (setq lst lst2))
      (if (eq lst2 nil) (setq lst lst1))
      (if (and lst1 lst2)
      (progn
      (foreach ent lst2
        (if (not (member ent lst1)) (setq lst (cons ent lst)))
      )
      (setq lst (append lst1 lst))
      )
      )
      (setq ss (ssadd))
      (foreach ent lst
        (ssadd ent ss)
      )
      ss
    )
    
    (defun c:test+ ( / ss1 ss2 )
      (prompt "\nFirst selection")
      (setq ss1 (ssget))
      (prompt "\nSecond selection")
      (setq ss2 (ssget))
      (sssetfirst nil (ss=ss1+ss2 ss1 ss2))
      (princ)
    )
    Code:
    (defun ss=ss1-ss2 ( ss1 ss2 / lst1 n1 lst2 n2 lst n ss )
      (setq n1 (if (vl-catch-all-error-p (vl-catch-all-apply 'sslength (list ss1))) 0 (sslength ss1)))
      (repeat n1
        (setq lst1 (cons (ssname ss1 (setq n1 (1- n1))) lst1))
      )
      (setq n2 (if (vl-catch-all-error-p (vl-catch-all-apply 'sslength (list ss2))) 0 (sslength ss2)))
      (repeat n2
        (setq lst2 (cons (ssname ss2 (setq n2 (1- n2))) lst2))
      )
      (if (eq lst1 nil) (setq lst nil))
      (if (eq lst2 nil) (setq lst lst1))
      (if (and lst1 lst2) (setq lst (append lst1 lst2)))
      (setq ss (ssadd))
      (foreach ent lst
        (if (and (not (member ent lst2)) (not (member ent (cdr (member ent lst))))) (ssadd ent ss))
      )
      ss
    )
    
    (defun c:test- ( / ss1 ss2 )
      (prompt "\nFirst selection")
      (setq ss1 (ssget))
      (prompt "\nSecond selection")
      (setq ss2 (ssget))
      (sssetfirst nil (ss=ss1-ss2 ss1 ss2))
      (princ)
    )
    Code:
    (defun remove_nth ( lst i )
      (setq i (1+ i))
      (vl-remove-if '(lambda (x) (zerop (setq i (1- i)))) lst)
    )
    
    (defun finddupel ( lst / n lstn )
      (setq n -1)
      (foreach el lst
        (if (member el (remove_nth lst (setq n (1+ n)))) (setq lstn (cons el lstn)))
      )
      (reverse lstn)
    )
    
    (defun unique ( l )
      (if l (cons (car l) (unique (vl-remove (car l) (cdr l)))))
    )
    
    (defun ss=ss1xss2 ( ss1 ss2 / lst1 n1 lst2 n2 lst n ss )
      (setq n1 (if (vl-catch-all-error-p (vl-catch-all-apply 'sslength (list ss1))) 0 (sslength ss1)))
      (repeat n1
        (setq lst1 (cons (ssname ss1 (setq n1 (1- n1))) lst1))
      )
      (setq n2 (if (vl-catch-all-error-p (vl-catch-all-apply 'sslength (list ss2))) 0 (sslength ss2)))
      (repeat n2
        (setq lst2 (cons (ssname ss2 (setq n2 (1- n2))) lst2))
      )
      (if (eq lst1 nil) (setq lst nil))
      (if (eq lst2 nil) (setq lst nil))
      (if (and lst1 lst2) (setq lst (unique (finddupel (append lst1 lst2)))))
      (setq ss (ssadd))
      (foreach ent lst
        (ssadd ent ss)
      )
      ss
    )
    
    (defun c:testx ( / ss1 ss2 )
      (prompt "\nFirst selection")
      (setq ss1 (ssget))
      (prompt "\nSecond selection")
      (setq ss2 (ssget))
      (sssetfirst nil (ss=ss1xss2 ss1 ss2))
      (princ)
    )
    Hope that someone will also find them useful (ss=ss1xss2) means intersection of ss1 and ss2... Inside this code there are also useful my sub-functions for manipulating with list (remove_nth) - modified (replace_nth) by Elpanov E. and CAB from www.theswamp.org, (finddupel) - this one is by me and it can be easy modified to (remalldupel) - just change (if (member el (remove_nth lst (setq n (1+ n)))) ...) to (if (not (member el (remove_nth lst (setq n (1+ n)))))...) and (unique) - Lee Mac witch is the same as predefined ACET-LIST-REMOVE-DUPLICATES only it don't need arg. to be supplied...
    Regards, M.R.
    Last edited by marko_ribar; 2012-04-15 at 07:53 PM.

  2. #2
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,719
    Login to Give a bone
    0

    Default Re: sel sets subfunctions

    Very kind of you to share, Marko... There's some neat code for others to go through.

    Here's [s]one[/s] some of mine that may interest you:

    Add selection sets -
    Code:
    (defun SS+ (ss1 ss2 / _ok i e eNames)
    
      (defun _ok (ss)
        (and (= 'PICKSET (type ss)) (< 0 (sslength ss))))
      
      (if (and (_ok ss1) (_ok ss2))
        (progn
          (foreach ss (list ss1 ss2)
            (setq i -1)
            (while (setq e (ssname ss (setq i (1+ i))))
              (if (not (vl-position e eNames))
                (setq eNames (cons e eNames)))))
          (setq ssNew (ssadd))
          (foreach e eNames (setq ssNew (ssadd e ssNew))))
        (prompt "\n** Invalid argument ** ")))
    Speed test (from console):
    Code:
    SS=SS1+SS2 
    _$ 
    
    SS+ 
    _$ (bench '(ss=ss1+ss2 SS+) '(ss1 ss2) 1000)
    
    SS=SS1+SS2
    Elapsed: 983
    Average: 0.9830
    
    SS+
    Elapsed: 156
    Average: 0.1560
    _$
    Remove items from a selection set -
    Code:
    (defun SS- (ss1 ss2 / _ok _ss->list ssNew)
    
      (defun _ok (ss)
        (and (= 'PICKSET (type ss)) (< 0 (sslength ss))))
    
      (defun _ss->list  (ss / i e eNames)
        (setq i -1)
        (while (setq e (ssname ss (setq i (1+ i))))
          (setq eNames (cons e eNames))))
      
      (if (and (_ok ss1) (_ok ss2))
        (progn
          (setq ssNew ss1)
          (foreach e (_ss->list ss2)
            (if (vl-position e (cond (ss) ((setq ss (_ss->list ss1)))))
              (setq ssNew (ssdel e ssNew)))))
        (prompt "\n** Invalid argument ** ")))
    Speed test (from console):
    Code:
    SS=SS1-SS2 
    _$ 
    
    SS- 
    _$ (bench '(ss=ss1-ss2 SS-) '(ss1 ss2) 1000)
    
    SS=SS1-SS2
    Elapsed: 998
    Average: 0.9980
    
    SS-
    Elapsed: 125
    Average: 0.1250
    _$

    Cheers!
    Last edited by RenderMan; 2012-04-02 at 04:41 PM.
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  3. #3
    Certifiable AUGI Addict
    Join Date
    2015-11
    Location
    Jo'burg SA
    Posts
    4,512
    Login to Give a bone
    0

    Default Re: sel sets subfunctions

    RM, I'm getting an error on your SS- function "; error: bad argument type: lselsetp nil". Though your ss+ works fine on the same arguments. Also you're reusing an argument as the selection set to be created. Please note that the ssadd will actually modify the original selection set if used this way.

    Anyhow, I've made 2 other versions. The first one is extremely simple:

    Add two selection sets together using simplest possible method.
    Code:
    (defun ss-union (ss1 ss2 / ss n)
      (setq n (sslength ss1)
            ss (ssadd))
      (while (>= (setq n (1- n)) 0) (ssadd (ssname ss1 n) ss))
      (setq n (sslength ss2))
      (while (>= (setq n (1- n)) 0) (ssadd (ssname ss2 n) ss))
      ss)
    Or the alternative method converting to lists first:
    Code:
    (defun ss-union2 (ss1 ss2 / ss)
      (setq ss (ssadd))
      (foreach e (list-union (ss->list ss1) (ss->list ss2)) (ssadd e ss))
      ss)
    
    (defun ss->list (ss / n lst)
      (setq n (sslength ss))
      (while (>= (setq n (1- n)) 0) (setq lst (cons (ssname ss n) lst)))
      lst)
    
    (defun list-subtract (lst1 lst2 / )
      (vl-remove-if (function (lambda (item) (vl-position item lst2))) lst1))
    
    (defun list-union (lst1 lst2 /  )
      (append lst1 (list-subtract lst2 lst1)))
    The list conversion seems to work the fastest here:
    Code:
    Benchmarking .........Elapsed milliseconds / relative speed for 64 iteration(s):
    
        (SS-UNION2 S1 S2)......1357 / 1.37 <fastest>
        (SS+ S1 S2)............1436 / 1.29
        (SS=SS1+SS2 S1 S2).....1840 / 1.01
        (SS-UNION S1 S2).......1857 / 1 <slowest>
    On the subtraction I'm doing a half-n-half idea first:
    Code:
    (defun ss-subtract (ss1 ss2 / ss n e elst)
      (setq elst (ss->list ss2)
            n (sslength ss1)
            ss (ssadd))	
      (while (>= (setq n (1- n)) 0)
        (if (not (vl-position (setq e (ssname ss1 n)) elst))
          (ssadd e ss)))
      ss)
    And then the full convert to list:
    Code:
    (defun ss-subtract2 (ss1 ss2 / ss)
      (setq ss (ssadd))
      (foreach e (list-subtract (ss->list ss1) (ss->list ss2)) (ssadd e ss))
      ss)
    Here both perform a lot faster than marko's. I can't test against yours - as there's the a fore mentioned error. Still converting both selection sets to lists and then using my list-subtract works fastest.
    Code:
    Benchmarking ..........Elapsed milliseconds / relative speed for 128 iteration(s):
    
        (SS-SUBTRACT2 S1 S2).....1092 / 3.74 <fastest>
        (SS-SUBTRACT S1 S2)......1154 / 3.54
        (SS=SS1-SS2 S1 S2).......4087 / 1 <slowest>
    Also since yours would modify the SS1 argument itself, this would affect the test from the 2nd iteration.

  4. #4
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,719
    Login to Give a bone
    0

    Default Re: sel sets subfunctions

    Quote Originally Posted by irneb View Post
    RM, I'm getting an error on your SS- function "; error: bad argument type: lselsetp nil". Though your ss+ works fine on the same arguments. Also you're reusing an argument as the selection set to be created. Please note that the ssadd will actually modify the original selection set if used this way.
    Irneb - The SS- function is contingent on ss2 being comprised of objects that also reside in ss1, otherwise there would be nothing to subtract from ss1. I have just again retested this functionality using a pseudo command (below) without issue. Perhaps you can confirm the data being selected for both ss1 and ss2, as it pertains to the SS- function?

    Code:
    (defun c:SS- ( / ss1 ss2)
      (if (and (setq ss1 (ssget "_:L"))
               (princ "\nNow select some of the same objects (just not all): ")
               (setq ss2 (ssget "_:L")))
        (sssetfirst nil (SS- ss1 ss2)))
      (princ))
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  5. #5
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,719
    Login to Give a bone
    0

    Default Re: sel sets subfunctions

    Quote Originally Posted by irneb View Post
    Here both perform a lot faster than marko's. I can't test against yours - as there's the a fore mentioned error. Still converting both selection sets to lists and then using my list-subtract works fastest.
    Code:
    Benchmarking ..........Elapsed milliseconds / relative speed for 128 iteration(s):
    
        (SS-SUBTRACT2 S1 S2).....1092 / 3.74 <fastest>
        (SS-SUBTRACT S1 S2)......1154 / 3.54
        (SS=SS1-SS2 S1 S2).......4087 / 1 <slowest>
    Ironically, it is now I who cannot test against yours...

    Code:
    SS-SUBTRACT
    ; error: bad argument type: lselsetp SS2
    _$ 
    
    SS-SUBTRACT2
    ; error: bad argument type: lselsetp SS1
    _$
    Quote Originally Posted by irneb View Post
    Also since yours would modify the SS1 argument itself, this would affect the test from the 2nd iteration.
    Just learned something here - I didn't realize that manipulating a selection set (when stored to another variable name) manipulates the original selection set. Speed test results are invalid for this test. Thanks for the check.
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  6. #6
    Certifiable AUGI Addict
    Join Date
    2015-11
    Location
    Jo'burg SA
    Posts
    4,512
    Login to Give a bone
    0

    Default Re: sel sets subfunctions

    For the test I did earlier I copied some entities in a drawing until I had about 500. Then made a selection set crossing over about half horizontally and another also about half vertically. So I ended up with 2 selection sets, each around 250 in size, with around 125 common entities. So I made this double now again, i.e. around 1000 objects:

    Here's the code copied from my Lisp console:
    Code:
    (setq s1 (ssget) s2 (ssget))
    <Selection set: a1109>
    _$ (sslength s1)
    521
    _$ (sslength s2)
    608
    _$ (length (list-intersect (ss->list s1) (ss->list s2)))
    335
    The list->intersect is an arb function thus:
    Code:
    (defun list-intersect (lst1 lst2 / ) (list-subtract lst1 (list-subtract lst1 lst2)))
    Now the benchmarking:
    Code:
    Benchmarking ..........Elapsed milliseconds / relative speed for 128 iteration(s):
        (SS-SUBTRACT2 S1 S2)......1560 / 7.06 <fastest>
        (SS-SUBTRACT S1 S2).......1575 / 6.99
        (SS=SS1-SS2 S1 S2).......11014 / 1 <slowest>
    
    Benchmarking ........Elapsed milliseconds / relative speed for 32 iteration(s):
        (SS-UNION2 S1 S2)......1138 / 1.7 <fastest>
        (SS+ S1 S2)............1201 / 1.61
        (SS-UNION S1 S2).......1466 / 1.32
        (SS=SS1+SS2 S1 S2).....1934 / 1 <slowest>

  7. #7
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,719
    Login to Give a bone
    0

    Default Re: sel sets subfunctions

    Perhaps I'll be able to redeem myself (on the SS- function) during lunch. LoL Obviously, you've done a great job revising the concept already. Not sure I'll be able to improve upon that. LoL

    I'm enjoying this thread... thanks for starting it, Marko.
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  8. #8
    All AUGI, all the time
    Join Date
    2015-10
    Location
    Belgrade, Serbia, Europe
    Posts
    564
    Login to Give a bone
    0

    Default Re: sel sets subfunctions

    Irneb, maybe you're wright about speed of your functions, but I am afraid that this is not an issue... If I chose one of sel sets to be nil (either ss1 or ss2), I get error lselsetp nil...

    My functions return exactly what is needed... That's why I used (vl-catch-all-apply)... Consider this situation where I successfully applied my (ss=ss1+ss2)... See here...

    Regards, M.R.

  9. #9
    Woo! Hoo! my 1st post
    Join Date
    2012-04
    Posts
    1
    Login to Give a bone
    0

    Default Re: sel sets subfunctions

    This is one of the most useful threads http://www.landlordinsurance.org.uk/ come across in a while Thanks guys!
    Last edited by lucindajane2307361189; 2012-05-18 at 09:25 AM.

  10. #10
    AUGI Addict
    Join Date
    2008-02
    Posts
    1,141
    Login to Give a bone
    0

    Default Re: sel sets subfunctions

    ssUnion food for thought...

    Code:
    (defun _ssUnion (ssList / add i)
      (setq add (ssadd))
      (foreach ss ssList
        (if (eq (type ss) 'PICKSET)
          (repeat (setq i (sslength ss)) (ssadd (ssname ss (setq i (1- i))) add))
        )
      )
      (cond ((> (sslength add) 0) add))
    )

Page 1 of 2 12 LastLast

Similar Threads

  1. more off sets
    By autocad.244673 in forum AMEP General
    Replies: 1
    Last Post: 2010-07-07, 01:43 AM
  2. Sheet sets.....
    By tcalabrese.210180 in forum AutoCAD Sheet Set Manager
    Replies: 1
    Last Post: 2009-06-14, 01:34 PM
  3. 3d max search sets
    By carty_girl in forum NavisWorks - General
    Replies: 0
    Last Post: 2009-03-31, 12:31 PM
  4. Sheet sets.....
    By tcalabrese.210180 in forum AutoCAD 3D (2007 and above)
    Replies: 1
    Last Post: 2009-03-01, 01:15 PM
  5. Printing ASD Sets
    By kathy71046 in forum AutoCAD Structural Detailing
    Replies: 0
    Last Post: 2009-02-04, 05:46 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •