Author Topic: selection set "by length"  (Read 7189 times)

0 Members and 1 Guest are viewing this topic.

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
selection set "by length"
« on: February 07, 2005, 01:27:40 PM »
Any way to speed up this process? So far I've tried these three variations.

Code: [Select]

;;; ============= number 1 ====================
(defun ss-by-length (lt / get-lgth ss ssf cntr ent lgth)
  ;; return a sset that contains all the LINES that are
  ;; greater than length (lt)

  (defun get-lgth (ent)
    (distance
      (cdr (assoc 10 (entget ent)))
      (cdr (assoc 11 (entget ent)))
      )
    )

  (gc)

  (setq ss (ssget "X" '((0 . "LINE")))
        ssf (ssadd)
        cntr 0
        )

  (if (> (sslength ss) 0)
    (repeat (1- (sslength ss))
            (setq ent (ssname ss cntr)
                  lgth (get-lgth ent)
                  )

            (if (> lgth lt)(setq ssf (ssadd ent ssf)))
            (setq cntr (1+ cntr))
            )
    )

  ssf
  )

;;; ============= number 2 ====================
(defun ss-by-length (lt / get-lgth ss ssf cntr ent lgth)
  ;; return a sset that contains all the LINES that are
  ;; greater than length (lt)

  (defun get-lgth (ent)
    (distance
      (cdr (assoc 10 (entget ent)))
      (cdr (assoc 11 (entget ent)))
      )
    )

  (gc)

  (setq ss (ssget "X" '((0 . "LINE")))
        ssf (ssadd)
        cntr 0
        )

  (if (> (sslength ss) 0)
    (while (setq ent (ssname ss cntr))

           (setq lgth (get-lgth ent))

           (if (> lgth lt)(setq ssf (ssadd ent ssf)))
           (setq cntr (1+ cntr))
           )
    )

  ssf
  )
 
;;; ============= number 3 ====================
(defun ss-by-length (lt / get-lgth ss ssf cntr ent lgth)
  ;; return a sset that contains all the LINES that are
  ;; greater than length (lt)

  (defun get-lgth (ent)
    (distance
      (cdr (assoc 10 (entget ent)))
      (cdr (assoc 11 (entget ent)))
      )
    )

  (gc)

  (setq ss (ssget "X" '((0 . "LINE")))
        cntr 0
        )

  (if (> (sslength ss) 0)
    (repeat (1- (sslength ss))
            (setq ent (ssname ss cntr)
                  lgth (get-lgth ent)
                  )

            (if (> lgth lt)(setq ss (ssdel ent ss)))
            (setq cntr (1+ cntr))
            )
    )

  ss
  )
TheSwamp.org  (serving the CAD community since 2003)

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
selection set "by length"
« Reply #1 on: February 07, 2005, 02:05:16 PM »
What if you rethink the idea?

For example, I'm a big believer in flexible functions. What if you had a function that was essentially a "remove ename from selection set if predicate function (that takes an entity name as the sole argument) is true?" kind of thing.

Not optimized, but ...

Code: [Select]
(defun SSRemoveIf ( QuotedFunction ss / i ename )
    (cond
        (   (eq 'pickset (type ss))
            (repeat (setq i (sslength ss))
                (if
                    (apply QuotedFunction
                        (list
                            (setq ename
                                (ssname ss (setq i (1- i)))
                            )    
                        )
                    )
                    (ssdel ename ss)
                )
            )
            (if (< 0 (sslength ss)) ss)
        )    
    )    
)

Then you could call it like ...
Code: [Select]
(SSRemoveIf
   '(lambda (ename)
        (<  (vla-get-length
                (vlax-ename->vla-object ename)
            )
            10 ;; remove all lines less than 10 units long
        )
    )
    (ssget "x" '((0 . "line")))
)


This is over simplified, you would probably need to employ robust error trapping; I wanted to keep it simple for idea clarity.

Just a thought.

Edit: Revised SSRemoveIf.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
selection set "by length"
« Reply #2 on: February 07, 2005, 03:05:37 PM »
Mark
How does this one fair?
I did not test it.
Code: [Select]
(defun ss-by-length (lt / ss ename elst)
  (and
    (setq ss (ssget "X" '((0 . "LINE"))))
    (setq i (sslength ss))
    (while (setq ename (ssname ss (setq i (1- i))))
      (setq elst (entget ename))
      (if (< (distance (cdr(assoc 10 elst))(cdr(assoc 11 elst))) lt)
        (ssdel ename ss))
    )
  )
  ss
)


EDIT: I think I fixed it... :?
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
selection set "by length"
« Reply #3 on: February 07, 2005, 06:31:41 PM »
Hey CAB -- it's not a good idea to iterate thru a selection set in a forward direction if you are modifying it (adding or removing members).

Also, I think you missed some cdr statements (does run fast when fixed up).

Cheers. :)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
selection set "by length"
« Reply #4 on: February 07, 2005, 07:05:57 PM »
Oooops, :oops:

Sorry about that. I did not think about that. The pointer would get lost.
That's what happens when you don't test your work. I can't write error free
code on the fly like you and Stig can. :)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
selection set "by length"
« Reply #5 on: February 07, 2005, 08:08:03 PM »
Quote from: CAB
I can't write error free code on the fly like you and Stig can. :)

I think you have me confused with someone else CAB -- I araely wrtie errro fere cdoe no teh fyl. :D
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

spacebuffalo

  • Guest
manipulating the ss by line length
« Reply #6 on: February 07, 2005, 08:13:42 PM »
the ss in the while loop is different than the returned ss...

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
selection set "by length"
« Reply #7 on: February 07, 2005, 08:30:54 PM »
I posted the repaired code, so Mark try it again. 8)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JohnK

  • Administrator
  • Seagull
  • Posts: 10660
selection set "by length"
« Reply #8 on: February 07, 2005, 08:57:49 PM »
>  I araely wrtie errro fere cdoe no teh fyl

:Oo:
I understood every word of that sentence. (Is that sad?! Do i really spell that bad. Do i really spell like "T I Double 'Grr'" speaks?)

:P
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
selection set "by length"
« Reply #9 on: February 08, 2005, 07:00:15 AM »
- CAB
that surely beats mine in a speed test. :D

- MP
That is truly ingenious! I would have never thought of that. I'm still looking at how I might  "optimized" that code.

Thanks for all the input guys.
TheSwamp.org  (serving the CAD community since 2003)

whdjr

  • Guest
selection set "by length"
« Reply #10 on: February 08, 2005, 08:11:11 AM »
MP,

How do you even think like that? :D

That is too cool!

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
selection set "by length"
« Reply #11 on: February 08, 2005, 08:36:38 AM »
Quote from: whdjr
MP,

How do you even think like that? :D

That is too cool!


"How, can you not think like that?" said MP the Lisp Master :)

It amazes me too, I think these folks have internalized the language and with
there creative talent it just flows out.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
selection set "by length"
« Reply #12 on: February 08, 2005, 10:45:43 AM »
Guys, it's not all that clever -- it's just an adaptation of functions we already have, like vl-remove-if.

:)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
selection set "by length"
« Reply #13 on: February 08, 2005, 12:18:37 PM »
Some quick notes on performance.

This code --

Code: [Select]
(SSRemoveIf
   '(lambda (ename)
        (<  (vla-get-length
                (vlax-ename->vla-object ename)
            )
            10 ;; remove all lines less than 10 units long
        )
    )
    (ssget "x" '((0 . "line")))
)


Is fine if the code will be executed once, but if the code will be executed multiple times, say in a process loop, better performance will be realized by committing the functionality to a formal function. This would remove the overhead associated with the creation of the temporary function for each iteration.

Example --

Code: [Select]
(defun Foo (ename)
    (<  (vla-get-length
            (vlax-ename->vla-object ename)
        )
        10 ;; remove all lines less than 10 units long
    )
)

(repeat n
    (cond
        (   (setq ss
                (SSRemoveIf
                   'Foo  ;; note, quoted function
                    (ssget "x" '((0 . "line")))
                )
            )
            ;;  now do something with the selection set ...
        )
    )
)


Still better performance can be realized if we remove the need for the function to be quoted:

Code: [Select]
(defun SSRemoveIf ( UnquotedFunction ss / i ename )
    (cond
        (   (eq 'pickset (type ss))
            (repeat (setq i (sslength ss))
                (if
                    (UnquotedFunction
                        (setq ename
                            (ssname ss (setq i (1- i)))
                        )    
                    )
                    (ssdel ename ss)
                )
            )
            (if (< 0 (sslength ss)) ss)
        )    
    )    
)


Now call it using an unquoted function --

Code: [Select]
(SSRemoveIf
    Foo ;; note, unquoted function call
    (ssget "x" '((0 . "line")))
)


Finally1, if you are writing an application that must run as fast as possible, using generic functions / structures like above are probably not the way to go. In that case I would likely hand roll each function specifically for each task.

Finally2, also note that there are differences between activex calls and dxf equivalents -- sometimes activex wins, sometimes it doesn't. You may have to do some benching.

Enjoy. :)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
selection set "by length"
« Reply #14 on: February 08, 2005, 12:44:09 PM »
Quote from: MP
Enjoy. :)


Oh .......... I am.  :D

Many thanks there MP.
TheSwamp.org  (serving the CAD community since 2003)