TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: well20152016 on November 10, 2016, 08:22:59 AM

Title: Automatic Nesting for lisp?
Post by: well20152016 on November 10, 2016, 08:22:59 AM
 Automatic Nesting
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 10, 2016, 09:51:32 AM
I need google to translate to for me known language... Sorry...

P.S. What is 2440x1220 in dialog box?
P.S.S. Now that you solved the task in 2D, my next advice for you is to try to solve it in 3D with boxes... (not obligation, just my remark...)
Title: Re: Automatic Nesting for lisp?
Post by: Master_Shake on November 10, 2016, 10:22:48 AM
I don't see a question here?
Title: Re: Automatic Nesting for lisp?
Post by: roy_043 on November 10, 2016, 10:25:11 AM
P.S. What is 2440x1220 in dialog box?
Probably the dimensions of a sheet of plywood.

@well20152016:
How about irregular shapes?
Title: Re: Automatic Nesting for lisp?
Post by: well20152016 on November 10, 2016, 11:08:53 AM
Many small rectangles, placed inside a large rectangle!
Title: Re: Automatic Nesting for lisp?
Post by: MP on November 10, 2016, 11:17:47 AM
(http://66.media.tumblr.com/13d96a63c28c2af2e62d1535098f129c/tumblr_ncdnts6dUj1sjaxuao1_400.jpg)
Title: Re: Automatic Nesting for lisp?
Post by: ElpanovEvgeniy on November 10, 2016, 11:53:41 AM
I have similar images  :-D
http://www.elpanov.com/index.php?id=69
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on November 10, 2016, 12:34:59 PM
I don't see a question here?
I have a question:
Code: [Select]
;--------|-----------------------------|-------------------|
;   10   | description        | string            |
;--------|-----------------------------|-------------------|
;   20   | length        | real              |
;--------|-----------------------------|-------------------|
;   30   | width        | real              |
;--------|-----------------------------|-------------------|
;   50   | preference index            | real              |
;--------|-----------------------------|-------------------|
;
(;Wood panel code
 ("CP09702220"  (10 . "Wood panel   970x2220")(20 .  970)(30 . 2220)(50 . 80))
 ("CP06152950"  (10 . "Wood panel   615x2950")(20 .  615)(30 . 2950)(50 . 20))
 ("CP14602950"  (10 . "Wood panel  1460x2950")(20 . 1460)(30 . 2950)(50 . 20))
)
;Example: CP14602950 = panel from commerce 1460x2950 - first dimension is the mood sense

; blade thickness = 3 (variable)

(;cutting list: quantity - length - width >  first dimension is the mood sense
  (3 1015 390) (57 490 1205) ...
)
Find the minimum number of panel proposing the computation starting at the highest preference index with the minimum number of rotations of the panel on the cutting machine (i.e. see the sequence A-B-C-D-F).
Does anyone know a similar program (also to buy)?

Title: Re: Automatic Nesting for lisp?
Post by: well20152016 on November 10, 2016, 01:46:25 PM
There should be a good algorithm, with the completion of lisp. Thank you
Title: Re: Automatic Nesting for lisp?
Post by: Lee Mac on November 10, 2016, 01:49:21 PM
I've always used (and continue to recommend) MyNesting (http://www.mynesting.com/) for this task.
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on November 11, 2016, 01:51:53 AM
I've always used (and continue to recommend) MyNesting (http://www.mynesting.com/) for this task.
Very interesting, but is there something about the cutting of wood panels with circular blade?
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on November 11, 2016, 09:02:11 AM
Sorry this is the correct schema (one rotation in less):
Title: Re: Automatic Nesting for lisp?
Post by: It's Alive! on November 11, 2016, 09:42:03 AM
grained and non grained materials? cutting tool thickness?
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on November 11, 2016, 11:12:18 AM
grained and non grained materials? cutting tool thickness?
Sorry for my english, I wrote "mood sense":
;Example: CP14602950 = panel from commerce 1460x2950 - first dimension is the mood sense
; blade thickness = 3 (variable)
;cutting list: quantity - length - width >  first dimension is the mood sense
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 11, 2016, 04:00:46 PM
Reply to animated gif... Not 100% sure, but this is my simple version... Should work with imaginary rectangular bounding boxes like posted gif, but my version is using one single rectangle for entity where nesting is expected...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:nesting ( / *adoc* ss s bndr minp maxp w h i e eminp emaxp ew eh el x y bp ell elll )
  2.  
  3.  
  4.   (prompt "\nSelect nesting 2D entities...")
  5.   (setq ss (ssget "_:L"))
  6.   (prompt "\nPick boundary rectangle to nest to...")
  7.   (setq s (ssget "_+.:E:S" (list '(0 . "LWPOLYLINE") '(90 . 4) '(-4 . "<or") '(70 . 1) '(70 . 129) '(-4 . "or>") '(-4 . "<not") '(-4 . "<>") '(42 . 0.0) '(-4 . "not>"))))
  8.   (setq bndr (ssname s 0))
  9.   (vla-getboundingbox (vlax-ename->vla-object bndr) 'minp 'maxp)
  10.   (mapcar 'set '(minp maxp) (mapcar 'safearray-value (list minp maxp)))
  11.   (setq w (- (car maxp) (car minp)))
  12.   (setq h (- (cadr maxp) (cadr minp)))
  13.   (repeat (setq i (sslength ss))
  14.     (setq e (ssname ss (setq i (1- i))))
  15.     (vla-getboundingbox (vlax-ename->vla-object e) 'eminp 'emaxp)
  16.     (mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
  17.     (setq ew (- (car emaxp) (car eminp)))
  18.     (setq eh (- (cadr emaxp) (cadr eminp)))
  19.     (setq el (cons (list eminp ew eh e) el))
  20.   )
  21.   (setq el (vl-sort el '(lambda ( a b ) (if (equal (caddr a) (caddr b) 1e-3) (< (cadr a) (cadr b)) (< (caddr a) (caddr b))))))
  22.   (while
  23.     (and
  24.       (car el)
  25.       (<
  26.         (cond
  27.           ( (null x) (setq x 0.0 y 0.0) x )
  28.           ( (> (+ x (cadar el)) w)
  29.             (setq x 0.0)
  30.             (foreach e elll
  31.               (setq ell (vl-remove e ell))
  32.             )
  33.             (setq elll ell)
  34.             (vl-some
  35.              '(lambda ( e )
  36.                 (if (< (cadar el) (car e))
  37.                   (setq y (+ (cadr e) (caddr (caddr e))))
  38.                 )
  39.               )
  40.               (reverse ell)
  41.             )
  42.             x
  43.           )
  44.           ( t
  45.             (if
  46.               (not
  47.                 (vl-some
  48.                  '(lambda ( e )
  49.                     (if (< (+ x (cadar el)) (car e))
  50.                       (setq y (+ (cadr e) (caddr (caddr e))))
  51.                     )
  52.                   )
  53.                   (reverse ell)
  54.                 )
  55.               )
  56.               (vl-some
  57.                '(lambda ( e )
  58.                   (if (or (< (+ x (cadar el)) (car e)) (< (+ x 1e-3) (car e)))
  59.                     (setq y (+ (cadr e) (caddr (caddr e))))
  60.                   )
  61.                 )
  62.                 (vl-sort ell '(lambda ( a b ) (> (car a) (car b))))
  63.               )
  64.             )
  65.             x
  66.           )
  67.         )
  68.         w
  69.       )
  70.       (or (< (+ y (caddar el)) h) (equal (+ y (caddar el)) h 1e-3))
  71.     )
  72.     (if (= x 0.0)
  73.       (setq bp (list (car minp) (+ y (cadr minp)) 0.0))
  74.       (setq bp (list (+ x (car minp)) (+ y (cadr minp)) 0.0))
  75.     )
  76.     (setq x (+ x (cadar el)))
  77.     (vla-move (vlax-ename->vla-object (cadddr (car el))) (vlax-3d-point (caar el)) (vlax-3d-point bp))
  78.     (setq ell (cons (list x y (car el)) ell))
  79.     (setq el (cdr el))
  80.   )
  81.   (vla-endundomark *adoc*)
  82.   (princ)
  83. )
  84.  

Regards, M.R.
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on November 12, 2016, 02:48:20 AM
Reply to animated gif... Not 100% sure, but this is my simple version... Should work with imaginary rectangular bounding boxes like posted gif, but my version is using one single rectangle for entity where nesting is expected...
<>
Regards, M.R.
Tested on my sample, this is the result:
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 12, 2016, 04:12:48 AM
Tested on my sample, this is the result:

Note that you must rotate all parts before "nesting.lsp" as it don't account for rotation - it just uses "move"... So if you have unsatisfied results this is the cause for that...
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on November 12, 2016, 04:53:17 AM
Tested on my sample, this is the result:

Note that you must rotate all parts before "nesting.lsp" as it don't account for rotation - it just uses "move"... So if you have unsatisfied results this is the cause for that...
The rotation is ok (I only draw a wrong cyan rectangle), this is the result:
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 12, 2016, 05:18:33 AM
There is a rule in my algorithm that is : rectangles that have smallest height comes first to be nested and nesting is processed from that rectangle to the rectangle that have largest height (not width)... Nesting is processed in arrays of rows from bottom to top row... There is no rotations... So your example isn't quite adequate for this kind of nesting, and I don't quite know how to program it for your case, but if it makes you more happy, change height of main rectangle so that last 2 parts jump in... You will then see that there is larger gap on the right side from which you can shrink bounding rectangle... The result should be almost the same looking in wasted material areas...

HTH, M.R.
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on November 12, 2016, 05:30:47 AM
There is a rule in my algorithm that is : rectangles that have smallest height comes first to be nested and nesting is processed from that rectangle to the rectangle that have largest height (not width)... Nesting is processed in arrays of rows from bottom to top row... There is no rotations... So your example isn't quite adequate for this kind of nesting, and I don't quite know how to program it for your case, but if it makes you more happy, change height of main rectangle so that last 2 parts jump in... You will then see that there is larger gap on the right side from which you can shrink bounding rectangle... The result should be almost the same looking in wasted material areas...

HTH, M.R.
Thanks Marko it is a good start.  :-)    But why not start from rectangles with largest heigth?
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 12, 2016, 06:24:57 AM
There is a rule in my algorithm that is : rectangles that have smallest height comes first to be nested and nesting is processed from that rectangle to the rectangle that have largest height (not width)... Nesting is processed in arrays of rows from bottom to top row... There is no rotations... So your example isn't quite adequate for this kind of nesting, and I don't quite know how to program it for your case, but if it makes you more happy, change height of main rectangle so that last 2 parts jump in... You will then see that there is larger gap on the right side from which you can shrink bounding rectangle... The result should be almost the same looking in wasted material areas...

HTH, M.R.
Thanks Marko it is a good start.  :-)    But why not start from rectangles with largest heigth?

If you try with various shapes of bounding boxes, you'll see that this is the most natural way... The smallest height on left from previous row is joined with little larger height - not the best, but that's the way the sorting is processed... So when next row comes the best way would be to join last from previous row with next row, but then nesting should be applied from right to left, and that means that no actual matching of left margin of bounding rectangle will be preserved while nesting... The way it's now operating is the most natural - with left margin, but as you can see in your example - often the routine is doing things making more waste of material than it should... Well, we have brains and we can make correct dispositions by intuition... It's just not possible to program that to computer in a few rows of codes... For me I am satisfied and how it works now - struggled a bit while finding correct alignment of next part with part from previous row, but I did it with using (vl-some) few times consecutively and I am pleased how results looked like in the end... Still for making it better I am afraid I need more experience and more brainstorming - predominantly theoretically... So the problem stays, but Lee offered some solution and I thought why not to do it straight away the fastest by coding this lisp...
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 12, 2016, 07:54:03 AM
Here is my improved version, based on explained statement that the best is to array from left to right and then from right to left based on heights... Only what's more important I preserved left margin so algorithm is practically the same, only I changed arrays of sorting by groups (rows) so that it's now alternative...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:nesting ( / *adoc* ss s bndr minp maxp w h i e eminp emaxp ew eh el eg egg k m x y yn bp ell elll )
  2.  
  3.  
  4.   (prompt "\nSelect nesting 2D entities...")
  5.   (setq ss (ssget "_:L"))
  6.   (prompt "\nPick boundary rectangle to nest to...")
  7.   (setq s (ssget "_+.:E:S" (list '(0 . "LWPOLYLINE") '(90 . 4) '(-4 . "<or") '(70 . 1) '(70 . 129) '(-4 . "or>") '(-4 . "<not") '(-4 . "<>") '(42 . 0.0) '(-4 . "not>"))))
  8.   (setq bndr (ssname s 0))
  9.   (vla-getboundingbox (vlax-ename->vla-object bndr) 'minp 'maxp)
  10.   (mapcar 'set '(minp maxp) (mapcar 'safearray-value (list minp maxp)))
  11.   (setq w (- (car maxp) (car minp)))
  12.   (setq h (- (cadr maxp) (cadr minp)))
  13.   (repeat (setq i (sslength ss))
  14.     (setq e (ssname ss (setq i (1- i))))
  15.     (vla-getboundingbox (vlax-ename->vla-object e) 'eminp 'emaxp)
  16.     (mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
  17.     (setq ew (- (car emaxp) (car eminp)))
  18.     (setq eh (- (cadr emaxp) (cadr eminp)))
  19.     (setq el (cons (list eminp ew eh e) el))
  20.   )
  21.   (setq el (vl-sort el '(lambda ( a b ) (if (equal (caddr a) (caddr b) 1e-3) (< (cadr a) (cadr b)) (< (caddr a) (caddr b))))))
  22.   (setq k 0.0 m 0)
  23.   (while (setq e (car el))
  24.     (setq k (+ k (cadr e)))
  25.     (if (< k w)
  26.       (setq eg (cons e eg))
  27.       (progn
  28.         (setq k 0.0 m (1+ m))
  29.         (if (= (rem m 2) 0)
  30.           (setq egg (cons eg egg))
  31.           (setq egg (cons (reverse eg) egg))
  32.         )
  33.         (setq eg nil k (+ k (cadr e)) eg (cons e eg))
  34.       )
  35.     )
  36.     (setq el (cdr el))
  37.   )
  38.   (if (not (vl-position (car eg) (apply 'append egg)))
  39.     (if (= (rem m 2) 1)
  40.       (setq egg (cons eg egg))
  41.       (setq egg (cons (reverse eg) egg))
  42.     )
  43.   )
  44.   (setq el (apply 'append (reverse egg)))
  45.   (while
  46.     (and
  47.       (car el)
  48.       (<
  49.         (cond
  50.           ( (null x) (setq x 0.0 y 0.0) x )
  51.           ( (> (+ x (cadar el)) w)
  52.             (setq x 0.0)
  53.             (foreach e elll
  54.               (setq ell (vl-remove e ell))
  55.             )
  56.             (setq elll ell)
  57.             (vl-some
  58.              '(lambda ( e )
  59.                 (if (< (cadar el) (car e))
  60.                   (setq y (+ (cadr e) (caddr (caddr e))))
  61.                 )
  62.               )
  63.               (reverse ell)
  64.             )
  65.             x
  66.           )
  67.           ( t
  68.             (if
  69.               (not
  70.                 (vl-some
  71.                  '(lambda ( e )
  72.                     (if (< (+ x (cadar el)) (car e))
  73.                       (setq yn (+ (cadr e) (caddr (caddr e))))
  74.                     )
  75.                   )
  76.                   (reverse ell)
  77.                 )
  78.               )
  79.               (vl-some
  80.                '(lambda ( e )
  81.                   (if (or (< (+ x (cadar el)) (car e)) (< (+ x 1e-3) (car e)))
  82.                     (setq yn (+ (cadr e) (caddr (caddr e))))
  83.                   )
  84.                 )
  85.                 (vl-sort ell '(lambda ( a b ) (> (car a) (car b))))
  86.               )
  87.             )
  88.             x
  89.           )
  90.         )
  91.         w
  92.       )
  93.       (if (> yn y)
  94.         (setq y yn)
  95.         y
  96.       )
  97.       (or (< (+ y (caddar el)) h) (equal (+ y (caddar el)) h 1e-3))
  98.     )
  99.     (if (= x 0.0)
  100.       (setq bp (list (car minp) (+ y (cadr minp)) 0.0))
  101.       (setq bp (list (+ x (car minp)) (+ y (cadr minp)) 0.0))
  102.     )
  103.     (setq x (+ x (cadar el)))
  104.     (vla-move (vlax-ename->vla-object (cadddr (car el))) (vlax-3d-point (caar el)) (vlax-3d-point bp))
  105.     (setq ell (cons (list x y (car el)) ell))
  106.     (setq el (cdr el))
  107.   )
  108.   (vla-endundomark *adoc*)
  109.   (princ)
  110. )
  111.  

HTH, M.R.

P.S. I don't think this will be useful for your example Marc', but generally it's much better...
Title: Re: Automatic Nesting for lisp?
Post by: well20152016 on November 13, 2016, 05:46:06 AM
Thanks Marko ,My level is limited, I can only learn about your lisp.


1, the area or the X direction from large to small array.
2, according to the order of the different working surface, the height is not more than the height of the ladder. The last loop to find the most suitable small rectangle into the rectangle.
Title: Re: Automatic Nesting for lisp?
Post by: well20152016 on November 13, 2016, 11:34:51 AM

Online to find some algorithms.
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 13, 2016, 02:53:10 PM
Your pictures very much remind me on TETRIS, but I don't want to dive into rotation functionality... If someone else is willing he/she is welcomed to jump in, I am satisfied with my version by now...
Title: Re: Automatic Nesting for lisp?
Post by: Grrr1337 on November 13, 2016, 03:17:02 PM
Your pictures very much remind me on TETRIS, but I don't want to dive into rotation functionality... If someone else is willing he/she is welcomed to jump in, I am satisfied with my version by now...
Why don't code something to play on TETRIS instead ?  :-D
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 14, 2016, 05:50:47 AM
I've noticed that on your example it works fine, but with random created rectangles it goes into endless loop...
Title: Re: Automatic Nesting for lisp?
Post by: well20152016 on November 14, 2016, 06:10:46 AM
My level is limited, the code is more chaotic! Influence speed!

I Know,
Y the direction of the conversion when there is bug, need to be modified?
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 14, 2016, 07:47:29 AM
The code is complex for me too... I've only formatted it better to be more readable and better for debugging... Only few my interventions - but generally it's the same code... Maybe you'll find it more operative in your quest for removing bug... Now only "code" tags...

Code: [Select]
(defun c:tt ( / get-rectangle-pts sort-XY count-ysame-ptr count-ysame-ptl *adoc* a aaa b base bbb1 bpts h i l0 lst lstt rts s ss sss sss1 w x y )

  (defun get-rectangle-pts ( en / pts )
    (setq pts
      (mapcar 'cdr
        (vl-remove-if-not
          (function
            (lambda ( x )
              (= (car x) 10)
            )
          ) (entget en)
        )
      )
    )
    (setq pts (sort-XY pts '(2 < <)) ) 
    (list (abs (- (caar pts) (caadr pts))) (abs (- (cadar pts) (cadr (cadddr pts)))) en pts)
  )

  (defun sort-XY ( lst fun / des des2 a )
    (defun des ( e1 e2 )
      ((eval (cadr fun)) (car e1) (car e2))
    )
    (defun des2 ( e1 e2 )
      ((eval (caddr fun)) (cadr e1) (cadr e2))
    )
    (cond
      ((= (car fun) 0) (vl-sort lst 'des))
      ((= (car fun) 1) (vl-sort lst 'des2))
      ((= (car fun) 2) (setq a (vl-sort lst 'des)) (vl-sort a 'des2))
      ((= (car fun) 3) (setq a (vl-sort lst 'des2)) (vl-sort a 'des))
    )
  )

  (defun count-ysame-ptr ( l / l1 l2 lst x )
    (while l
      (setq x (car l)
            l (cdr l)
           l1 (list x)
      )
      (foreach a l
        (if (equal (cadr x) (cadr a) 1e-3)
          (setq l1 (cons a l1))
          (setq l2 (cons a l2))
        )
      )
      (setq lst (cons l1 lst) l l2 l2 nil)
    )
    (setq lst
      (mapcar (function (lambda ( e )
        (car
          (vl-sort e (function (lambda ( e1 e2 )
            (> (car e1) (car e2))
          )))
        )
        )) lst
      )
    )
    (vl-sort lst (function (lambda ( e1 e2 ) (< (cadr e1) (cadr e2)))))
  )

  (defun count-ysame-ptl ( l bb / l1 l2 lst lst2 x )
    (while l
      (setq x (car l)
            l (cdr l)
           l1 (list x)
      )
      (foreach a l
        (if (equal (cadr x) (cadr a) 1e-3)
          (setq l1 (cons a l1))
          (setq l2 (cons a l2))
        )
      )
      (setq lst (cons l1 lst) l l2 l2 nil)
    )
    (setq lst
      (mapcar (function (lambda ( e )
        (car
          (vl-sort e (function (lambda ( e1 e2 )
            (< (car e1) (car e2))
          )))
        )
        )) lst
      )
    )
    (setq lst2 nil)
    (foreach a (vl-sort lst (function (lambda ( e1 e2 ) (> (cadr e1) (cadr e2)))))
      (if (> (cadr a) bb)
        (setq lst2 (cons a lst2))
      )
    )
    lst2
  )

  (vl-load-com)

  (vla-startundomark (setq *adoc* (vla-get-activedocument (vlax-get-acad-object))))
  (prompt "\nSelect nesting 2D entities...")
  (setq ss (ssget (list '(0 . "LWPOLYLINE") '(90 . 4) '(-4 . "<or") '(70 . 1) '(70 . 129) '(-4 . "or>") '(-4 . "<not") '(-4 . "<>") '(42 . 0.0) '(-4 . "not>"))))
  (prompt "\nPick boundary rectangle to nest to...")
  (setq s (ssget "_+.:E:S" (list '(0 . "LWPOLYLINE") '(90 . 4) '(-4 . "<or") '(70 . 1) '(70 . 129) '(-4 . "or>") '(-4 . "<not") '(-4 . "<>") '(42 . 0.0) '(-4 . "not>"))))
  (if ss (setq lst (mapcar (function (lambda ( x ) (get-rectangle-pts x))) (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))))
  (if s  (setq l0 (get-rectangle-pts (ssname s 0)) w (car l0) h (cadr l0) bpts (list (car (last l0)))))
  (setq lst (vl-sort lst (function (lambda ( a b ) (if (equal (cadr a) (cadr b) 1e-3) (> (car a) (car b)) (> (cadr a) (cadr b)))))))

  (setq i 0 lstt nil base (cadar (last l0)))
  (while lst
    (setq aaa
      (mapcar (function (lambda ( y )
        (mapcar (function (lambda ( x )
          (if (cdr bpts)
            (if
              (and
                (>= (- w (- (car y) (caar (last l0))) (car x)) 0)
                (>= (- (cadadr bpts) (cadr y) (cadr x)) 0)
              )
              x
            )
            (if
              (and
                (>= (- w (- (car y) (caar (last l0))) (car x)) 0)
                (>= (- h (cadr y) (cadr x)) 0)
              )
              x
            )
          ))) lst
        )
        )) bpts
      )
    )
    (if (apply 'or (apply 'append aaa))
      (progn
        (setq bbb1
          (car
            (setq sss1
              (vl-remove nil
                (setq sss
                  (mapcar (function (lambda ( x y )
                    (if (vl-remove nil x)
                      (list (vl-remove nil x) y)
                    )
                    )) aaa bpts
                  )
                )
              )
            )
          )
        )
        (setq aaa (caar bbb1))
        (vla-move (vlax-ename->vla-object (caddr aaa)) (vlax-3d-point (car (last aaa))) (vlax-3d-point (cadr bbb1)))
        (setq bpts
          (count-ysame-ptr
            (append
              (list (mapcar '+ (car bpts) (list (car aaa) 0)))
              bpts
            )
          )
        )
        (setq lstt (cons (caddr aaa) lstt))
        (setq lst
          (vl-remove-if (function (lambda ( b )
            (equal aaa b))) lst
          )
        )
        (setq base
          (cadar
            (last
              (get-rectangle-pts (caddr aaa))
            )
          )
        )
      ); then progn
      (progn
        (setq rts
          (count-ysame-ptl
            (apply 'append
              (mapcar 'last
                (mapcar (function (lambda ( x )
                  (get-rectangle-pts x))) lstt
                )
              )
            ) base
          )
        )
        (setq bpts
          (reverse
            (cons
              (list (caar (last l0)) (cadr (last rts)))
              (cdr (reverse rts))
            )
          )
        )
      ); else progn
    ); if
    (setq i (1+ i))
  ); while
  (vla-endundomark *adoc*)
  (princ)
)
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on November 14, 2016, 12:52:12 PM
Test on my simple DWG it goes into endless loop... (AutoCAD/Bricscad), see attached.
Title: Re: Automatic Nesting for lisp?
Post by: LULU1965 on November 15, 2016, 12:34:47 AM
I introduce myself my name is Luciano and 30 years working on Autocad 2d and 3d.
I have a problem that now haunts for years and only you "GURU" of the Lisp language you can perhaps bring myself giving me a great HAND.Vi thank you in advance. Best Regards M.L.
Title: Re: Automatic Nesting for lisp?
Post by: LULU1965 on November 15, 2016, 12:49:38 AM
TOO BIG EXCUSE ME!!!! (PURGE)
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on November 15, 2016, 02:23:37 AM
TOO BIG EXCUSE ME!!!! (PURGE)
Luciano, puoi editare il tuo messaggio precedente e togliere l'allegato (mi pare che si possa fare) cosė non appesantisce il server. Ciao.
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 15, 2016, 06:33:48 AM
Luciano, your DWG is showing the task human should do manually... No algorithm for this...

Marc'Antonio, I've managed to improve a little my version - added rotation functionality and changed a little sorting method... I'll attach DWG so that you can confirm slightly change in size of original master plate - should fit all pieces and waste of material is unavoidable - so this is as far as it can go for now by computation of lisp...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:nesting ( / *adoc* ss s bndr minp maxp w h i e eminp emaxp ew eh el eg egg k m x y yn bp ell elll )
  2.  
  3.  
  4.   (prompt "\nSelect nesting 2D entities...")
  5.   (setq ss (ssget "_:L"))
  6.   (prompt "\nPick boundary rectangle to nest to...")
  7.   (setq s (ssget "_+.:E:S" (list '(0 . "LWPOLYLINE") '(90 . 4) '(-4 . "<or") '(70 . 1) '(70 . 129) '(-4 . "or>") '(-4 . "<not") '(-4 . "<>") '(42 . 0.0) '(-4 . "not>"))))
  8.   (setq bndr (ssname s 0))
  9.   (vla-getboundingbox (vlax-ename->vla-object bndr) 'minp 'maxp)
  10.   (mapcar 'set '(minp maxp) (mapcar 'safearray-value (list minp maxp)))
  11.   (setq w (- (car maxp) (car minp)))
  12.   (setq h (- (cadr maxp) (cadr minp)))
  13.   (repeat (setq i (sslength ss))
  14.     (setq e (ssname ss (setq i (1- i))))
  15.     (vla-getboundingbox (vlax-ename->vla-object e) 'eminp 'emaxp)
  16.     (mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
  17.     (setq ew (- (car emaxp) (car eminp)))
  18.     (setq eh (- (cadr emaxp) (cadr eminp)))
  19.     (if (> ew eh)
  20.       (progn
  21.         (vla-rotate (vlax-ename->vla-object e) (vlax-3d-point (mapcar '/ (mapcar '+ eminp emaxp) (list 2.0 2.0 2.0))) (* 0.5 pi))
  22.         (vla-getboundingbox (vlax-ename->vla-object e) 'eminp 'emaxp)
  23.         (mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
  24.         (setq ew (- (car emaxp) (car eminp)))
  25.         (setq eh (- (cadr emaxp) (cadr eminp)))
  26.       )
  27.     )
  28.     (setq el (cons (list eminp ew eh e) el))
  29.   )
  30.   (setq el (vl-sort el '(lambda ( a b ) (if (equal (caddr a) (caddr b) 1e-3) (< (cadr a) (cadr b)) (< (caddr a) (caddr b))))))
  31.   ;|
  32.   (setq k 0.0 m 0)
  33.   (while (setq e (car el))
  34.     (setq k (+ k (cadr e)))
  35.     (if (< k w)
  36.       (setq eg (cons e eg))
  37.       (progn
  38.         (setq k 0.0 m (1+ m))
  39.         (if (= (rem m 2) 0)
  40.           (setq egg (cons eg egg))
  41.           (setq egg (cons (reverse eg) egg))
  42.         )
  43.         (setq eg nil k (+ k (cadr e)) eg (cons e eg))
  44.       )
  45.     )
  46.     (setq el (cdr el))
  47.   )
  48.   (if (not (vl-position (car eg) (apply 'append egg)))
  49.     (if (= (rem m 2) 1)
  50.       (setq egg (cons eg egg))
  51.       (setq egg (cons (reverse eg) egg))
  52.     )
  53.   )
  54.   (setq el (apply 'append (reverse egg)))
  55.   |;
  56.   (while
  57.     (and
  58.       (car el)
  59.       (<
  60.         (cond
  61.           ( (null x) (setq x 0.0 y 0.0) x )
  62.           ( (> (+ x (cadar el)) w)
  63.             (setq x 0.0)
  64.             (foreach e elll
  65.               (setq ell (vl-remove e ell))
  66.             )
  67.             (setq elll ell)
  68.             (setq y (+ (cadr (car (reverse ell))) (caddr (caddr (car (reverse ell))))))
  69.             (vl-some
  70.              '(lambda ( e )
  71.                 (if (< (cadar el) (+ (car e) 1e-3))
  72.                   (setq yn (+ (cadr e) (caddr (caddr e))))
  73.                 )
  74.               )
  75.               (reverse ell)
  76.             )
  77.             (if (> yn y)
  78.               (setq y yn)
  79.             )
  80.             x
  81.           )
  82.           ( t
  83.             (if
  84.               (not
  85.                 (vl-some
  86.                  '(lambda ( e )
  87.                     (if (< (+ x (cadar el)) (+ (car e) 1e-3))
  88.                       (setq yn (+ (cadr e) (caddr (caddr e))))
  89.                     )
  90.                   )
  91.                   (reverse ell)
  92.                 )
  93.               )
  94.               (vl-some
  95.                '(lambda ( e )
  96.                   (if (or (< (+ x (cadar el)) (car e)) (< (+ x 1e-3) (car e)))
  97.                     (setq yn (+ (cadr e) (caddr (caddr e))))
  98.                   )
  99.                 )
  100.                 (vl-sort ell '(lambda ( a b ) (> (car a) (car b))))
  101.               )
  102.             )
  103.             (if (> yn y)
  104.               (setq y yn)
  105.             )
  106.             x
  107.           )
  108.         )
  109.         w
  110.       )
  111.       (or (< (+ y (caddar el)) h) (equal (+ y (caddar el)) h 1e-3))
  112.     )
  113.     (if (= x 0.0)
  114.       (setq bp (list (car minp) (+ y (cadr minp)) 0.0))
  115.       (setq bp (list (+ x (car minp)) (+ y (cadr minp)) 0.0))
  116.     )
  117.     (setq x (+ x (cadar el)))
  118.     (vla-move (vlax-ename->vla-object (cadddr (car el))) (vlax-3d-point (caar el)) (vlax-3d-point bp))
  119.     (setq ell (cons (list x y (car el)) ell))
  120.     (setq el (cdr el))
  121.   )
  122.   (vla-endundomark *adoc*)
  123.   (princ)
  124. )
  125.  

Regards, M.R.
Title: Re: Automatic Nesting for lisp?
Post by: m4rdy on November 15, 2016, 07:05:44 AM
This is good start too for learn if anybody know delphi/pascal (Unfortunately, I don't).
http://delphiforfun.org/Programs/CutList.htm (http://delphiforfun.org/Programs/CutList.htm)
http://delphiforfun.org/Programs/tilefit.htm (http://delphiforfun.org/Programs/tilefit.htm)
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 15, 2016, 08:39:52 AM
Changed part of code - last intervention till now :

Code: [Select]
      ...
      (<
        (cond
          ( (null x) (setq x 0.0 y 0.0) x )
          ( (> (+ x (cadar el)) w)
            (setq x 0.0)
            (foreach e elll
              (setq ell (vl-remove e ell))
            )
            (setq elll ell)
            (setq y (+ (cadr (car (reverse ell))) (caddr (caddr (car (reverse ell))))))
            (vl-some
             '(lambda ( e )
                (if (< (cadar el) (+ (car e) 1e-3))
                  (setq yn (+ (cadr e) (caddr (caddr e))))
                )
              )
              (reverse ell)
            )
            (if (> yn y)
              (setq y yn)
            )
            x
          )
          ( t
            (if
              (not
                (vl-some
                 '(lambda ( e )
                    (if (< (+ x (cadar el)) (+ (car e) 1e-3))
                      (setq yn (+ (cadr e) (caddr (caddr e))))
                    )
                  )
                  (reverse ell)
                )
              )
              (vl-some
               '(lambda ( e )
                  (if (or (< (+ x (cadar el)) (car e)) (< (+ x 1e-3) (car e)))
                    (setq yn (+ (cadr e) (caddr (caddr e))))
                  )
                )
                (vl-sort ell '(lambda ( a b ) (> (car a) (car b))))
              )
            )
            (if (> yn y)
              (setq y yn)
            )
            x
          )
        )
        w
      )
      ...
Title: Re: Automatic Nesting for lisp?
Post by: well20152016 on November 15, 2016, 08:41:08 AM
thank!Marko !
I have no time today, another day!
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 15, 2016, 08:53:50 AM
Ooops, I've changed my revision...
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on November 15, 2016, 09:54:09 AM
Ooops, I've changed my revision...
This is the result, but in my sample I do not need to rotate the rectangles, they are in the rigth rotation, grazie ancora.
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 15, 2016, 10:30:11 AM
After more researching, I've found that alternative disposition of rectangles from left to right and then in next row from right to left has some lacks - while grouping in revising order groups are different than afterward row calculation as groups are alternatively reversed and therefore dimension in afterward row calculation may jump in from different group (next one) - this causes that method can't be reliable and therefore I've returned my code in previous state - sorting and disposition is going only from left to right by rows and height of boxes are growing constantly... My code revised now - look in my last posted colored code tag...
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 15, 2016, 10:34:31 AM
This is what my nesting is doing... Red rectangle is modified one, and green one is yours Marc'Antonio...
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on November 15, 2016, 12:20:43 PM
This is what my nesting is doing... Red rectangle is modified one, and green one is yours Marc'Antonio...
Ok, thanks I will try to see if I can understand how it works.    :-)
Title: Re: Automatic Nesting for lisp?
Post by: well20152016 on November 15, 2016, 08:52:48 PM
Ooops, I've changed my revision...


Why don't you try it out from the big to the small
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on November 16, 2016, 12:36:59 AM
Ooops, I've changed my revision...


Why don't you try it out from the big to the small

I'll leave that intervention to the user that has followed discussion... It's only one sign problematic...
Title: Re: Automatic Nesting for lisp?
Post by: LULU1965 on November 16, 2016, 10:52:51 AM
E' POSSIBILE FARE QUESTO LISP CON LA POSSIBILITA DI SELEZIONARE UN MAGGIOR NUMERO DI "Pick boundary rectangle to nest to..." MULTIPLI
QUELLO SENZA ROTAZIONE DELLE PARTI PIU' PICCOLE CHE VENGONO INNESTATE.

(defun c:tt ( / *adoc* a aaa b base bbb1 bpts h i l0 lst lstt rts s ss sss sss1 w x y)

SCUSATEMI PER IL DISTURBO "GRAZIE
----------------------------------------------------------------------------------------------------------------------------------------------------------------
IS POSSIBLE TO MAKE THIS LISP WITH THE OPPORTUNITY TO SELECT A HIGHER NUMBER OF "Pick boundary rectangle to nest to ..." MULTIPLE
IS WITHOUT ROTATING PARTS MORE 'SMALL THAT ARE GRAFTED.

(Defun c: tt (/ * * adoc a aaa b basis bbb1 bp h i l0 lst LSTT rts s ss sss SSS1 w x y)

Sorry for DISORDER "THANK YOU" THANKS





Title: Re: Automatic Nesting for lisp?
Post by: well20152016 on December 04, 2016, 10:52:26 AM
How many kinds of large rectangular size by n small rectangle?

Result:((200 10) (180 10) (160 10) (140 10) (120 10) (100 20) (80 20) (60 30) (40 50)
(20 100))

Code - Auto/Visual Lisp: [Select]
  1. (defun c:tt()
  2.   (setq w 20 l 10 n 10)
  3.   (setq p (getpoint"\n insertion point") b p i 1 lst nil)
  4.   (repeat n
  5.     (repeat i
  6.        (repeat (fix(/ n i)) (LM:ENTMAKE-LWPOLYLINE (4boxs b w l)) (setq b (polar b 0 l)))
  7.         (setq b (list (car p) (+ w (cadr b)))))
  8.     (setq lst (cons(list (* i w) (* (fix(/ n i)) l)) lst) i (1+ i))
  9.     (setq b (list (car p) (+ (cadr b) 4)))
  10.     )
  11. (princ "\n")
  12. (princ lst)
  13.  
  14. (defun 4boxs (p w l)
  15.   (list p  (polar p (* 0.5 pi) w) (polar (polar p 0 l) (* 0.5 pi) w)  (polar p 0 l))
  16. )
  17.  
  18. (defun LM:ENTMAKE-LWPOLYLINE (lst  / p)
  19.               (list (cons 0 "LWPOLYLINE")
  20.                     (cons 100 "AcDbEntity")
  21.                     (cons 100 "AcDbPolyline")
  22.                     (cons 90 (length lst) )
  23.                     (cons 70 1 )
  24.                     (cons 62 2 )
  25.               )
  26.               (mapcar(function (lambda (p) (cons 10 p)))lst)
  27. )))    
  28.  
Title: Re: Automatic Nesting for lisp?
Post by: LULU1965 on December 04, 2016, 02:05:58 PM
Minimum possibile number of platea .... Thanks forma all Grazie tanto
Title: Re: Automatic Nesting for lisp?
Post by: roy_043 on December 04, 2016, 08:27:13 PM
@well20152016:
I think the result should be:
((200 10) (100 20) (40 50) (20 100))
Title: Re: Automatic Nesting for lisp?
Post by: well20152016 on December 06, 2016, 07:51:18 AM
Code - Auto/Visual Lisp: [Select]
  1.  
  2. result:((200 10) (100 20) (40 50) (20 100))
  3.  
  4. (defun c:tt()
  5.   (setq w 20 l 10 n 10)
  6.   (setq p (getpoint"\n insertion point") b p i 1 lst nil)
  7.   (repeat n
  8.    (if (equal (rem n i) 0 0) (progn
  9.     (repeat i
  10.        (repeat (fix(/ n i)) (LM:ENTMAKE-LWPOLYLINE (4boxs b w l)) (setq b (polar b 0 l)))
  11.         (setq b (list (car p) (+ w (cadr b)))))
  12.     (setq lst (cons(list (* i w) (* (fix(/ n i)) l)) lst) )))
  13.     (setq i (1+ i))
  14.     (setq b (list (car p) (+ (cadr b) 4)))
  15.     )
  16. (princ "\n")
  17. (princ lst)
  18.  
  19. (defun 4boxs (p w l)
  20.   (list p  (polar p (* 0.5 pi) w) (polar (polar p 0 l) (* 0.5 pi) w)  (polar p 0 l))
  21. )
  22.  
  23. (defun LM:ENTMAKE-LWPOLYLINE (lst  / p)
  24.               (list (cons 0 "LWPOLYLINE")
  25.                     (cons 100 "AcDbEntity")
  26.                     (cons 100 "AcDbPolyline")
  27.                     (cons 90 (length lst) )
  28.                     (cons 70 1 )
  29.                     (cons 62 2 )
  30.               )
  31.               (mapcar(function (lambda (p) (cons 10 p)))lst)
  32. )))
  33.  
  34.  
Title: Re: Automatic Nesting for lisp?
Post by: ahsattarian on January 19, 2021, 02:28:36 PM
This works on several sheets   :



Code - Auto/Visual Lisp: [Select]
  1. (defun c:nest ()
  2.   (prompt "\n Select nesting 2D entities : ")
  3.   (setq ss1 (ssget "_:L"))
  4.   (prompt "\n Pick boundary rectangle to nest to :")
  5.   (setq filter (list '(0 . "lwpolyline") '(90 . 4) '(-4 . "<or") '(70 . 1) '(70 . 129) '(-4 . "or>") '(-4 . "<not") '(-4 . "<>") '(42 . 0.0)
  6.                      '(-4 . "not>"))
  7.   )
  8.   ;;(setq ss2 (ssget "_+.:E:S" filter))
  9.   (setq ss2 (ssget filter))
  10.   (setq el nil)
  11.   (setq n1 (sslength ss1))
  12.   (setq k1 -1)
  13.   (repeat n1
  14.     (setq k1 (1+ k1))
  15.     (setq s1 (ssname ss1 k1))
  16.     (setq obj1 (vlax-ename->vla-object s1))
  17.     (vla-getboundingbox obj1 'eminp 'emaxp)
  18.     (mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
  19.     (setq ew (- (car emaxp) (car eminp)))
  20.     (setq eh (- (cadr emaxp) (cadr eminp)))
  21.     (cond
  22.       ((> ew eh)
  23.        (setq po (mapcar '/ (mapcar '+ eminp emaxp) (list 2.0 2.0 2.0)))
  24.        (vla-rotate obj1 (vlax-3d-point po) (* 0.5 pi))
  25.        (vla-getboundingbox obj1 'eminp 'emaxp)
  26.        (mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
  27.        (setq ew (- (car emaxp) (car eminp)))
  28.        (setq eh (- (cadr emaxp) (cadr eminp)))
  29.       )
  30.     )
  31.     (setq el (cons (list eminp ew eh s1) el))
  32.   )
  33.   (setq el (vl-sort el
  34.                     '(lambda (a b)
  35.                        (if (equal (caddr a) (caddr b) 1e-3)
  36.                          (< (cadr a) (cadr b))
  37.                          (< (caddr a) (caddr b))
  38.                        )
  39.                      )
  40.            )
  41.   )
  42.   (setq n2 (sslength ss2))
  43.   (setq k2 -1)
  44.   (repeat n2
  45.     (setq k2 (1+ k2))
  46.     (setq s2 (ssname ss2 k2))
  47.     (setq obj2 (vlax-ename->vla-object s2))
  48.     (vla-getboundingbox obj2 'minp 'maxp)
  49.     (mapcar 'set '(minp maxp) (mapcar 'safearray-value (list minp maxp)))
  50.     (setq w (- (car maxp) (car minp)))
  51.     (setq h (- (cadr maxp) (cadr minp)))
  52.     (setq x nil)
  53.     (setq y nil)
  54.     (setq yn nil)
  55.     (setq ell nil)
  56.     (setq elll nil)
  57.     (while
  58.       (and
  59.         (car el)
  60.         (cond
  61.           ((null x) (setq x 0.0) (setq y 0.0) (setq f x))
  62.           ((> (+ x (cadar el)) w)
  63.            (setq x 0.0)
  64.            (foreach e elll (setq ell (vl-remove e ell)))
  65.            (setq elll ell)
  66.            (setq y (+ (cadr (car (reverse ell))) (caddr (caddr (car (reverse ell))))))
  67.            (vl-some '(lambda (e) (cond ((< (cadar el) (+ (car e) 1e-3)) (setq yn (+ (cadr e) (caddr (caddr e)))))))
  68.                     (reverse ell)
  69.            )
  70.            (cond ((> yn y) (setq y yn)))
  71.            (setq f x)
  72.           )
  73.           (t
  74.            (if
  75.              (not
  76.                (vl-some '(lambda (e) (cond ((< (+ x (cadar el)) (+ (car e) 1e-3)) (setq yn (+ (cadr e) (caddr (caddr e)))))))
  77.                         (reverse ell)
  78.                )
  79.              )
  80.               (vl-some
  81.                 '(lambda (e)
  82.                    (cond ((or (< (+ x (cadar el)) (car e)) (< (+ x 1e-3) (car e))) (setq yn (+ (cadr e) (caddr (caddr e))))))
  83.                  )
  84.                 (vl-sort ell '(lambda (a b) (> (car a) (car b))))
  85.               )
  86.            )
  87.            (cond ((> yn y) (setq y yn)))
  88.            (setq f x)
  89.           )
  90.         )
  91.         (< f w)
  92.         (or (< (+ y (caddar el)) h) (equal (+ y (caddar el)) h 1e-3))
  93.       )
  94.        (if (= x 0.0)
  95.          (setq bp (list (car minp) (+ y (cadr minp)) 0.0))
  96.          (setq bp (list (+ x (car minp)) (+ y (cadr minp)) 0.0))
  97.        )
  98.        (setq x (+ x (cadar el)))
  99.        (vla-move (vlax-ename->vla-object (cadddr (car el))) (vlax-3d-point (caar el)) (vlax-3d-point bp))
  100.        (setq ell (cons (list x y (car el)) ell))
  101.        (setq el (cdr el))
  102.     )
  103.   )
  104.   (princ)
  105. )




Title: Re: Automatic Nesting for lisp?
Post by: ScottMC on January 21, 2021, 06:53:13 PM
NICE lsp y'all!!

Tried for a bit to get the vars assigned and won't give.. responds with:

 Command: NEST
; error: too few arguments

[a b bp e eh el ell elll ew f h k1 k2 n n2 n1 s1 s2
ss1 ss2 t w x y yn filter obj1 po eminp emaxp maxp minp]

vlide responds saying the "t" var is incorrect.

just feel safer having those vars assigned Thanks

Really like it for cut file setup!
Title: Re: Automatic Nesting for lisp?
Post by: ahsattarian on January 24, 2021, 11:59:01 AM
Hello

T   is not used in my LISP  above  !!!

It works in my laptop.

R U sure about it????
Title: Re: Automatic Nesting for lisp?
Post by: ScottMC on January 24, 2021, 07:06:39 PM
Must be the "t" is not a variable .. really WAY over my head!

          (t   
           (if
             (not
               (vl-some

had to play with it [takes alot for me to understand] still
like it very much but still would like to assign the local vars..
any help would be REALLY appreciated!!  :idiot2:
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on February 03, 2021, 09:22:03 AM
It works! This is my test:
Title: Re: Automatic Nesting for lisp?
Post by: ScottMC on April 30, 2021, 11:55:58 AM
Just to ease the cad-vars.. here's the working list for "Nest":
( / a b bp e eh el ell elll ew f h k1 k2 n n2 n1 s1 s2 ss1 ss2 w x yy yn filter obj1 obj2 po eminp emaxp maxp minp )
Title: Re: Automatic Nesting for lisp?
Post by: ronjonp on April 30, 2021, 04:57:43 PM
Just to ease the cad-vars.. here's the working list for "Nest":
( / a b bp e eh el ell elll ew f h k1 k2 n n2 n1 s1 s2 ss1 ss2 w x yy yn filter obj1 obj2 po eminp emaxp maxp minp )
I've tried to educate this poster a few times on localizing variables but it fell on deaf ears.  :roll:
Title: Re: Automatic Nesting for lisp?
Post by: ScottMC on May 01, 2021, 06:46:49 PM
I've seen others which place a combined (setq xx nil..) later in the code. Why they choose this as it could clear vars out on other working pgms...  ouch
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on June 10, 2021, 02:48:04 AM
Another one :
https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/i-m-trying-to-pack-objects-inside-a-rectangle-minimum-space-lost/m-p/10378327/highlight/true#M416005

Regards, M.R.
Title: Re: Automatic Nesting for lisp?
Post by: ScottMC on June 10, 2021, 11:00:04 AM
Very useful tool! I use this to rearrange how items are placed on a CNC for cut. The one thing I tried was to offset each for the cut-path to ease re-arrangement but it refuses 'group' items. The other, which would sell, is asking for rotation restraint or orientation to make the wood grain be in the right direction according to the 'Picked' Rectangle. Besides my comments, what you did engineered is very helpful. Thanks
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on June 11, 2021, 11:29:17 AM
I've added error handler, calculation of UNDO steps after finish and changed order of generating "l" list of (bp dx dy) so that when first pass of (main) function finishes it checks from lower left corner of main boundary for "bp"s again and not as it was from upper right to lower left... That's one thing in main routine "nesting.lsp" and I tried to make additional "nesting-new.lsp" with (process2rec) function that would try to implement checking of relation of 2 rectangles in processing nesting - all I could think of is that with this checking it's sometimes different choice of processing order of entities from list "el"... Marc's example with bigger main boundary is solvable by "nesting-new.lsp" and first DWG is somewhat better with original "nesting.lsp"... If someone has something new based on "nesting.lsp" it would be good to try to improve it, or post an opinion of what could be better and (or) relevant to this topic... Thanks for attention...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:nesting ( / *error* car-sort insiderec process main adoc cmde ss s i e minpt maxpt dx dy el lw bp l ll al ka kb )
  2.  
  3.  
  4.   (defun *error* ( m )
  5.     (if cmde
  6.       (setvar 'cmdecho cmde)
  7.     )
  8.     (if adoc
  9.       (vla-endundomark adoc)
  10.     )
  11.     (if m
  12.       (prompt m)
  13.     )
  14.     (princ)
  15.   )
  16.  
  17.   (defun car-sort ( lst cmp / rtn )
  18.     (setq rtn (car lst))
  19.     (foreach itm (cdr lst)
  20.       (if (apply cmp (list itm rtn))
  21.         (setq rtn itm)
  22.       )
  23.     )
  24.     rtn
  25.   )
  26.  
  27.   (defun insiderec ( ll ur p )
  28.     (and
  29.       (< (car ll) (car p) (car ur))
  30.       (< (cadr ll) (cadr p) (cadr ur))
  31.     )
  32.   )
  33.  
  34.   (defun process ( el bp dx dy / e1 e2 dd1 dd2 e )
  35.     (if (= 8 (logand 8 (getvar 'undoctl)))
  36.       (vla-endundomark adoc)
  37.     )
  38.     (vla-startundomark adoc)
  39.     (setq ka (1+ ka))
  40.     (setq kb (1+ kb))
  41.     (setq e1 (car-sort
  42.                (vl-remove-if '(lambda ( x )
  43.                                 (or
  44.                                   (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list 1e-3 1e-3)))) al)
  45.                                   (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list (caadr x) 0.0) (list -1e-3 1e-3)))) al)
  46.                                   (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list 0.0 (cadadr x)) (list 1e-3 -1e-3)))) al)
  47.                                   (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list (caadr x) (cadadr x)) (list -1e-3 -1e-3)))) al)
  48.                                   (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list (* (caadr x) 0.5) (* (cadadr x) 0.5))))) al)
  49.                                   (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (caadr x) (cadadr x))) (car y))) al)
  50.                                   (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (caadr x) (cadadr x))) (mapcar '+ (car y) (list (- (caadr y) (caar y)) 0.0)))) al)
  51.                                   (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (caadr x) (cadadr x))) (cadr y))) al)
  52.                                   (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (caadr x) (cadadr x))) (mapcar '+ (car y) (list 0.0 (- (cadadr y) (cadar y)))))) al)
  53.                                   (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (caadr x) (cadadr x))) (mapcar '+ (car y) (list (* (- (caadr y) (caar y)) 0.5) (* (- (cadadr y) (cadar y)) 0.5))))) al)
  54.                                   (minusp (- dx (caadr x)))
  55.                                   (minusp (- dy (cadadr x)))
  56.                                 )
  57.                  ) el
  58.                ) '(lambda ( a b ) (< (min (- dx (caadr a)) (- dy (cadadr a))) (min (- dx (caadr b)) (- dy (cadadr b)))))))
  59.     (setq e2 (car-sort
  60.                (vl-remove-if '(lambda ( x )
  61.                                 (or
  62.                                   (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list 1e-3 1e-3)))) al)
  63.                                   (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list (cadadr x) 0.0) (list -1e-3 1e-3)))) al)
  64.                                   (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list 0.0 (caadr x)) (list 1e-3 -1e-3)))) al)
  65.                                   (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list (cadadr x) (caadr x)) (list -1e-3 -1e-3)))) al)
  66.                                   (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list (* (cadadr x) 0.5) (* (caadr x) 0.5))))) al)
  67.                                   (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (cadadr x) (caadr x))) (car y))) al)
  68.                                   (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (cadadr x) (caadr x))) (mapcar '+ (car y) (list (- (caadr y) (caar y)) 0.0)))) al)
  69.                                   (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (cadadr x) (caadr x))) (cadr y))) al)
  70.                                   (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (cadadr x) (caadr x))) (mapcar '+ (car y) (list 0.0 (- (cadadr y) (cadar y)))))) al)
  71.                                   (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (cadadr x) (caadr x))) (mapcar '+ (car y) (list (* (- (caadr y) (caar y)) 0.5) (* (- (cadadr y) (cadar y)) 0.5))))) al)
  72.                                   (minusp (- dx (cadadr x)))
  73.                                   (minusp (- dy (caadr x)))
  74.                                 )
  75.                  ) el
  76.                ) '(lambda ( a b ) (< (min (- dx (cadadr a)) (- dy (caadr a))) (min (- dx (cadadr b)) (- dy (caadr b)))))))
  77.     (cond
  78.       ( (and e1 e2)
  79.         (setq dd1 (min (- dx (caadr e1)) (- dy (cadadr e1))))
  80.         (setq dd2 (min (- dx (cadadr e2)) (- dy (caadr e2))))
  81.         (if (< dd1 dd2)
  82.           (setq e e1)
  83.           (progn
  84.             (vla-rotate (vlax-ename->vla-object (car e2)) (vlax-3d-point (caddr e2)) (* 0.5 pi))
  85.             (vla-move (vlax-ename->vla-object (car e2)) (vlax-3d-point '(0 0)) (vlax-3d-point (mapcar '+ '(0 0) (list (cadadr e2) 0.0))))
  86.             (setq e (subst (list (cadadr e2) (caadr e2)) (cadr e2) e2))
  87.           )
  88.         )
  89.       )
  90.       ( (and e1 (null e2))
  91.         (setq e e1)
  92.       )
  93.       ( (and e2 (null e1))
  94.         (vla-rotate (vlax-ename->vla-object (car e2)) (vlax-3d-point (caddr e2)) (* 0.5 pi))
  95.         (vla-move (vlax-ename->vla-object (car e2)) (vlax-3d-point '(0 0)) (vlax-3d-point (mapcar '+ '(0 0) (list (cadadr e2) 0.0))))
  96.         (setq e (subst (list (cadadr e2) (caadr e2)) (cadr e2) e2))
  97.       )
  98.     )
  99.     e
  100.   )
  101.  
  102.   (defun main ( el bp dx dy )
  103.     (if (setq e (process el bp dx dy))
  104.       (progn
  105.         (setq al (cons (list bp (mapcar '+ bp (list (caadr e) (cadadr e)))) al))
  106.         (setq l (append l (list (list (mapcar '+ bp (list (caadr e) 0.0)) (- dx (caadr e)) dy))))
  107.         (setq l (append l (list (list (mapcar '+ bp (list 0.0 (cadadr e))) dx (- dy (cadadr e))))))
  108.         (setq l (append l (list (list (mapcar '+ bp (list (caadr e) (cadadr e))) (- dx (caadr e)) (- dy (cadadr e))))))
  109.         (setq l (vl-remove-if '(lambda ( x ) (vl-some '(lambda ( y ) (equal (car x) y 1e-6)) (mapcar 'car al))) l))
  110.         (if
  111.           (and
  112.             (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list 1e-3 1e-3)))) (cdr al)))
  113.             (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list (caadr e) 0.0) (list -1e-3 1e-3)))) (cdr al)))
  114.             (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list 0.0 (cadadr e)) (list 1e-3 -1e-3)))) (cdr al)))
  115.             (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list (caadr e) (cadadr e)) (list -1e-3 -1e-3)))) (cdr al)))
  116.             (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list (* (caadr e) 0.5) (* (cadadr e) 0.5))))) (cdr al)))
  117.             (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (car x))) (cdr al)))
  118.             (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (mapcar '+ (car x) (list (- (caadr x) (caar x)) 0.0)))) (cdr al)))
  119.             (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (cadr x))) (cdr al)))
  120.             (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (mapcar '+ (car x) (list 0.0 (- (cadadr x) (cadar x)))))) (cdr al)))
  121.             (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (mapcar '+ (car x) (list (* (- (caadr x) (caar x)) 0.5) (* (- (cadadr x) (cadar x)) 0.5))))) (cdr al)))
  122.           )
  123.           (progn
  124.             (vla-move (vlax-ename->vla-object (car e)) (vlax-3d-point (caddr e)) (vlax-3d-point bp))
  125.             (setq el (vl-remove-if '(lambda ( x ) (eq (car x) (car e))) el))
  126.             (cond
  127.               ( (process el (mapcar '+ bp (list (caadr e) 0.0)) (- dx (caadr e)) dy)
  128.                 (vl-cmdf "_.undo" "_b")
  129.                 (setq kb (1- kb))
  130.                 (main el (mapcar '+ bp (list (caadr e) 0.0)) (- dx (caadr e)) dy)
  131.               )
  132.               ( (process el (mapcar '+ bp (list 0.0 (cadadr e))) dx (- dy (cadadr e)))
  133.                 (vl-cmdf "_.undo" "_b")
  134.                 (setq kb (1- kb))
  135.                 (main el (mapcar '+ bp (list 0.0 (cadadr e))) dx (- dy (cadadr e)))
  136.               )
  137.               ( (process el (mapcar '+ bp (list (caadr e) (cadadr e))) (- dx (caadr e)) (- dy (cadadr e)))
  138.                 (vl-cmdf "_.undo" "_b")
  139.                 (setq kb (1- kb))
  140.                 (main el (mapcar '+ bp (list (caadr e) (cadadr e))) (- dx (caadr e)) (- dy (cadadr e)))
  141.               )
  142.               ( t el )
  143.             )
  144.           )
  145.           el
  146.         )
  147.       )
  148.       el
  149.     )
  150.   )
  151.  
  152.   (if (= 8 (logand 8 (getvar 'undoctl)))
  153.     (vla-endundomark adoc)
  154.   )
  155.   (setq cmde (getvar 'cmdecho))
  156.   (setvar 'cmdecho 0)
  157.   (setq ka 0)
  158.   (setq kb 0)
  159.   (if
  160.     (and
  161.       (not (prompt "\nSelect parts for nesting..."))
  162.       (setq ss (ssget "_:L"))
  163.       (not (prompt "\nPick boundary RECTANGLE..."))
  164.       (setq s (ssget "_+.:E:S" (list '(0 . "LWPOLYLINE") '(90 . 4) '(-4 . "&=") '(70 . 1) '(-4 . "<not") '(-4 . "<>") '(42 . 0.0) '(-4 . "not>"))))
  165.     )
  166.     (progn
  167.       (repeat (setq i (sslength ss))
  168.         (setq e (ssname ss (setq i (1- i))))
  169.         (vla-getboundingbox (vlax-ename->vla-object e) 'minpt 'maxpt)
  170.         (mapcar 'set '(minpt maxpt) (mapcar 'safearray-value (list minpt maxpt)))
  171.         (setq dx (- (car maxpt) (car minpt)))
  172.         (setq dy (- (cadr maxpt) (cadr minpt)))
  173.         (setq el (cons (list e (list dx dy) minpt) el))
  174.       )
  175.       (setq lw (ssname s 0))
  176.       (vla-getboundingbox (vlax-ename->vla-object lw) 'minpt 'maxpt)
  177.       (mapcar 'set '(minpt maxpt) (mapcar 'safearray-value (list minpt maxpt)))
  178.       (setq dx (- (car maxpt) (car minpt)))
  179.       (setq dy (- (cadr maxpt) (cadr minpt)))
  180.       (setq bp minpt)
  181.       (setq el (main el bp dx dy))
  182.       (while (and el (setq ll (car l)))
  183.         (setq l (cdr l))
  184.         (mapcar 'set '(bp dx dy) ll)
  185.         (setq el (main el bp dx dy))
  186.       )
  187.       (prompt "\nType \"UNDO\" ") (princ ka) (prompt " for back if you are using AutoCAD...")
  188.       (prompt "\nType \"UNDO\" ") (princ kb) (prompt " for back if you are using BricsCAD...")
  189.     )
  190.   )
  191.   (*error* nil)
  192. )
  193.  
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on June 11, 2021, 11:29:46 AM
Quote
I've added error handler, calculation of UNDO steps after finish and changed order of generating "l" list of (bp dx dy) so that when first pass of (main) function finishes it checks from lower left corner of main boundary for "bp"s again and not as it was from upper right to lower left... That's one thing in main routine "nesting.lsp" and I tried to make additional "nesting-new.lsp" with (process2rec) function that would try to implement checking of relation of 2 rectangles in processing nesting - all I could think of is that with this checking it's sometimes different choice of processing order of entities from list "el"... Marc's example with bigger main boundary is solvable by "nesting-new.lsp" and first DWG is somewhat better with original "nesting.lsp"... If someone has something new based on "nesting.lsp" it would be good to try to improve it, or post an opinion of what could be better and (or) relevant to this topic... Thanks for attention...

Here is "nesting-new.lsp" (look on previous page for "nesting.lsp")
http://www.theswamp.org/index.php?topic=52260.msg605093#msg605093


Code - Auto/Visual Lisp: [Select]
  1. (defun c:nesting-new ( / *error* car-sort insiderec process2rec process main adoc cmde ss s i e minpt maxpt dx dy el lw bp l ll al ka kb f )
  2.  
  3.  
  4.   (defun *error* ( m )
  5.     (if cmde
  6.       (setvar 'cmdecho cmde)
  7.     )
  8.     (if adoc
  9.       (vla-endundomark adoc)
  10.     )
  11.     (if m
  12.       (prompt m)
  13.     )
  14.     (princ)
  15.   )
  16.  
  17.   (defun car-sort ( lst cmp / rtn )
  18.     (setq rtn (car lst))
  19.     (foreach itm (cdr lst)
  20.       (if (apply cmp (list itm rtn))
  21.         (setq rtn itm)
  22.       )
  23.     )
  24.     rtn
  25.   )
  26.  
  27.   (defun insiderec ( ll ur p )
  28.     (and
  29.       (< (car ll) (car p) (car ur))
  30.       (< (cadr ll) (cadr p) (cadr ur))
  31.     )
  32.   )
  33.  
  34.   (defun process2rec ( e el / dx1 dy1 dx2 dy2 ddxy1 ddxy2 ddxy3 ddxy4 ddxy5 ddxy6 ddxy7 ddxy8 a1 a2 a3 a4 a5 a6 a7 a8 r )
  35.     (if (and e (> (length el) 1))
  36.       (progn
  37.         (setq dx1 (caadr e))
  38.         (setq dy1 (cadadr e))
  39.         (foreach ee (vl-remove e el)
  40.           (setq dx2 (caadr ee))
  41.           (setq dy2 (cadadr ee))
  42.           (setq ddxy1 (list (+ dx1 dx2) (max dy1 dy2))) ;;; right side e normal ee normal
  43.           (setq ddxy2 (list (+ dx1 dy2) (max dy1 dx2))) ;;; right side e normal ee rotated
  44.           (setq ddxy3 (list (+ dy1 dx2) (max dx1 dy2))) ;;; right side e rotated ee normal
  45.           (setq ddxy4 (list (+ dy1 dy2) (max dx1 dx2))) ;;; right side e rotated ee rotated
  46.           (setq ddxy5 (list (max dx1 dx2) (+ dy1 dy2))) ;;; up side e normal ee normal
  47.           (setq ddxy6 (list (max dx1 dy2) (+ dy1 dx2))) ;;; up side e normal ee rotated
  48.           (setq ddxy7 (list (max dy1 dx2) (+ dx1 dy2))) ;;; up side e rotated ee normal
  49.           (setq ddxy8 (list (max dy1 dy2) (+ dx1 dx2))) ;;; up side e rotated ee rotated
  50.           (mapcar 'set '(a1 a2 a3 a4 a5 a6 a7 a8) (mapcar '(lambda ( x ) (* (car x) (cadr x))) (list ddxy1 ddxy2 ddxy3 ddxy4 ddxy5 ddxy6 ddxy7 ddxy8)))
  51.           (setq r (cons (list (- a1 (* dx1 dy1) (* dx2 dy2)) (list e ee) ddxy1 "1") r))
  52.           (setq r (cons (list (- a2 (* dx1 dy1) (* dx2 dy2)) (list e ee) ddxy2 "2") r))
  53.           (setq r (cons (list (- a3 (* dx1 dy1) (* dx2 dy2)) (list e ee) ddxy3 "3") r))
  54.           (setq r (cons (list (- a4 (* dx1 dy1) (* dx2 dy2)) (list e ee) ddxy4 "4") r))
  55.           (setq r (cons (list (- a5 (* dx1 dy1) (* dx2 dy2)) (list e ee) ddxy5 "5") r))
  56.           (setq r (cons (list (- a6 (* dx1 dy1) (* dx2 dy2)) (list e ee) ddxy6 "6") r))
  57.           (setq r (cons (list (- a7 (* dx1 dy1) (* dx2 dy2)) (list e ee) ddxy7 "7") r))
  58.           (setq r (cons (list (- a8 (* dx1 dy1) (* dx2 dy2)) (list e ee) ddxy8 "8") r))
  59.         )
  60.         (car-sort r '(lambda ( a b ) (if (= (car a) (car b)) (< (* (car (caddr a)) (cadr (caddr a))) (* (car (caddr b)) (cadr (caddr b)))) (< (car a) (car b)))))
  61.       )
  62.     )
  63.   )
  64.  
  65.   (defun process ( el bp dx dy / e1 e2 dd1 dd2 e r )
  66.     (if (= 8 (logand 8 (getvar 'undoctl)))
  67.       (vla-endundomark adoc)
  68.     )
  69.     (vla-startundomark adoc)
  70.     (setq ka (1+ ka))
  71.     (setq kb (1+ kb))
  72.     (setq f nil)
  73.     (if (> (length el) 1)
  74.       (progn
  75.         (foreach e el
  76.           (setq r (cons (process2rec e el) r))
  77.         )
  78.         (setq r (car-sort
  79.                   (vl-remove-if '(lambda ( x )
  80.                                    (or
  81.                                      (minusp (- dx (car (caddr x))))
  82.                                      (minusp (- dy (cadr (caddr x))))
  83.                                    )
  84.                                  ) r
  85.                   ) '(lambda ( a b ) (< (min (- dx (car (caddr a))) (- dy (cadr (caddr a)))) (min (- dx (car (caddr b))) (- dy (cadr (caddr b))))))))
  86.       )
  87.     )
  88.     (if r
  89.       (if (or (= (last r) "1") (= (last r) "2") (= (last r) "5") (= (last r) "6"))
  90.         (progn
  91.           (setq e (caadr r))
  92.           (if
  93.             (not
  94.               (and
  95.                 (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list 1e-3 1e-3)))) al))
  96.                 (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list (caadr e) 0.0) (list -1e-3 1e-3)))) al))
  97.                 (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list 0.0 (cadadr e)) (list 1e-3 -1e-3)))) al))
  98.                 (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list (caadr e) (cadadr e)) (list -1e-3 -1e-3)))) al))
  99.                 (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list (* (caadr e) 0.5) (* (cadadr e) 0.5))))) al))
  100.                 (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (car x))) al))
  101.                 (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (mapcar '+ (car x) (list (- (caadr x) (caar x)) 0.0)))) al))
  102.                 (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (cadr x))) al))
  103.                 (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (mapcar '+ (car x) (list 0.0 (- (cadadr x) (cadar x)))))) al))
  104.                 (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (mapcar '+ (car x) (list (* (- (caadr x) (caar x)) 0.5) (* (- (cadadr x) (cadar x)) 0.5))))) al))
  105.               )
  106.             )
  107.             (setq e nil)
  108.           )
  109.         )
  110.         (progn
  111.           (setq e (caadr r))
  112.           (if
  113.             (not
  114.               (and
  115.                 (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list 1e-3 1e-3)))) al))
  116.                 (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list (cadadr e) 0.0) (list -1e-3 1e-3)))) al))
  117.                 (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list 0.0 (caadr e)) (list 1e-3 -1e-3)))) al))
  118.                 (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list (cadadr e) (caadr e)) (list -1e-3 -1e-3)))) al))
  119.                 (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list (* (cadadr e) 0.5) (* (caadr e) 0.5))))) al))
  120.                 (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (cadadr e) (caadr e))) (car x))) al))
  121.                 (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (cadadr e) (caadr e))) (mapcar '+ (car x) (list (- (caadr x) (caar x)) 0.0)))) al))
  122.                 (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (cadadr e) (caadr e))) (cadr x))) al))
  123.                 (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (cadadr e) (caadr e))) (mapcar '+ (car x) (list 0.0 (- (cadadr x) (cadar x)))))) al))
  124.                 (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (cadadr e) (caadr e))) (mapcar '+ (car x) (list (* (- (caadr x) (caar x)) 0.5) (* (- (cadadr x) (cadar x)) 0.5))))) al))
  125.               )
  126.             )
  127.             (setq e nil)
  128.           )
  129.           (if e
  130.             (setq f t)
  131.           )
  132.         )
  133.       )
  134.     )
  135.     (if (null e)
  136.       (progn
  137.         (setq e1 (car-sort
  138.                    (vl-remove-if '(lambda ( x )
  139.                                     (or
  140.                                       (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list 1e-3 1e-3)))) al)
  141.                                       (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list (caadr x) 0.0) (list -1e-3 1e-3)))) al)
  142.                                       (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list 0.0 (cadadr x)) (list 1e-3 -1e-3)))) al)
  143.                                       (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list (caadr x) (cadadr x)) (list -1e-3 -1e-3)))) al)
  144.                                       (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list (* (caadr x) 0.5) (* (cadadr x) 0.5))))) al)
  145.                                       (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (caadr x) (cadadr x))) (car y))) al)
  146.                                       (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (caadr x) (cadadr x))) (mapcar '+ (car y) (list (- (caadr y) (caar y)) 0.0)))) al)
  147.                                       (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (caadr x) (cadadr x))) (cadr y))) al)
  148.                                       (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (caadr x) (cadadr x))) (mapcar '+ (car y) (list 0.0 (- (cadadr y) (cadar y)))))) al)
  149.                                       (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (caadr x) (cadadr x))) (mapcar '+ (car y) (list (* (- (caadr y) (caar y)) 0.5) (* (- (cadadr y) (cadar y)) 0.5))))) al)
  150.                                       (minusp (- dx (caadr x)))
  151.                                       (minusp (- dy (cadadr x)))
  152.                                     )
  153.                                   ) el
  154.                    ) '(lambda ( a b ) (< (min (- dx (caadr a)) (- dy (cadadr a))) (min (- dx (caadr b)) (- dy (cadadr b)))))))
  155.         (setq e2 (car-sort
  156.                    (vl-remove-if '(lambda ( x )
  157.                                     (or
  158.                                       (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list 1e-3 1e-3)))) al)
  159.                                       (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list (cadadr x) 0.0) (list -1e-3 1e-3)))) al)
  160.                                       (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list 0.0 (caadr x)) (list 1e-3 -1e-3)))) al)
  161.                                       (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list (cadadr x) (caadr x)) (list -1e-3 -1e-3)))) al)
  162.                                       (vl-some '(lambda ( y ) (insiderec (car y) (cadr y) (mapcar '+ bp (list (* (cadadr x) 0.5) (* (caadr x) 0.5))))) al)
  163.                                       (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (cadadr x) (caadr x))) (car y))) al)
  164.                                       (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (cadadr x) (caadr x))) (mapcar '+ (car y) (list (- (caadr y) (caar y)) 0.0)))) al)
  165.                                       (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (cadadr x) (caadr x))) (cadr y))) al)
  166.                                       (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (cadadr x) (caadr x))) (mapcar '+ (car y) (list 0.0 (- (cadadr y) (cadar y)))))) al)
  167.                                       (vl-some '(lambda ( y ) (insiderec bp (mapcar '+ bp (list (cadadr x) (caadr x))) (mapcar '+ (car y) (list (* (- (caadr y) (caar y)) 0.5) (* (- (cadadr y) (cadar y)) 0.5))))) al)
  168.                                       (minusp (- dx (cadadr x)))
  169.                                       (minusp (- dy (caadr x)))
  170.                                     )
  171.                                   ) el
  172.                    ) '(lambda ( a b ) (< (min (- dx (cadadr a)) (- dy (caadr a))) (min (- dx (cadadr b)) (- dy (caadr b)))))))
  173.         (cond
  174.           ( (and e1 e2)
  175.             (setq dd1 (min (- dx (caadr e1)) (- dy (cadadr e1))))
  176.             (setq dd2 (min (- dx (cadadr e2)) (- dy (caadr e2))))
  177.             (if (< dd1 dd2)
  178.               (setq e e1)
  179.               (progn
  180.                 (vla-rotate (vlax-ename->vla-object (car e2)) (vlax-3d-point (caddr e2)) (* 0.5 pi))
  181.                 (vla-move (vlax-ename->vla-object (car e2)) (vlax-3d-point '(0 0)) (vlax-3d-point (mapcar '+ '(0 0) (list (cadadr e2) 0.0))))
  182.                 (setq e (subst (list (cadadr e2) (caadr e2)) (cadr e2) e2))
  183.               )
  184.             )
  185.           )
  186.           ( (and e1 (null e2))
  187.             (setq e e1)
  188.           )
  189.           ( (and e2 (null e1))
  190.             (vla-rotate (vlax-ename->vla-object (car e2)) (vlax-3d-point (caddr e2)) (* 0.5 pi))
  191.             (vla-move (vlax-ename->vla-object (car e2)) (vlax-3d-point '(0 0)) (vlax-3d-point (mapcar '+ '(0 0) (list (cadadr e2) 0.0))))
  192.             (setq e (subst (list (cadadr e2) (caadr e2)) (cadr e2) e2))
  193.           )
  194.         )
  195.       )
  196.     )
  197.     e
  198.   )
  199.  
  200.   (defun main ( el bp dx dy )
  201.     (if (setq e (process el bp dx dy))
  202.       (progn
  203.         (if f
  204.           (progn
  205.             (vla-rotate (vlax-ename->vla-object (car e)) (vlax-3d-point (caddr e)) (* 0.5 pi))
  206.             (vla-move (vlax-ename->vla-object (car e)) (vlax-3d-point '(0 0)) (vlax-3d-point (mapcar '+ '(0 0) (list (cadadr e) 0.0))))
  207.             (setq e (subst (list (cadadr e) (caadr e)) (cadr e) e))
  208.           )
  209.         )
  210.         (setq al (cons (list bp (mapcar '+ bp (list (caadr e) (cadadr e)))) al))
  211.         (setq l (append l (list (list (mapcar '+ bp (list (caadr e) 0.0)) (- dx (caadr e)) dy))))
  212.         (setq l (append l (list (list (mapcar '+ bp (list 0.0 (cadadr e))) dx (- dy (cadadr e))))))
  213.         (setq l (append l (list (list (mapcar '+ bp (list (caadr e) (cadadr e))) (- dx (caadr e)) (- dy (cadadr e))))))
  214.         (setq l (vl-remove-if '(lambda ( x ) (vl-some '(lambda ( y ) (equal (car x) y 1e-6)) (mapcar 'car al))) l))
  215.         (if
  216.           (and
  217.             (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list 1e-3 1e-3)))) (cdr al)))
  218.             (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list (caadr e) 0.0) (list -1e-3 1e-3)))) (cdr al)))
  219.             (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list 0.0 (cadadr e)) (list 1e-3 -1e-3)))) (cdr al)))
  220.             (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list (caadr e) (cadadr e)) (list -1e-3 -1e-3)))) (cdr al)))
  221.             (not (vl-some '(lambda ( x ) (insiderec (car x) (cadr x) (mapcar '+ bp (list (* (caadr e) 0.5) (* (cadadr e) 0.5))))) (cdr al)))
  222.             (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (car x))) (cdr al)))
  223.             (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (mapcar '+ (car x) (list (- (caadr x) (caar x)) 0.0)))) (cdr al)))
  224.             (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (cadr x))) (cdr al)))
  225.             (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (mapcar '+ (car x) (list 0.0 (- (cadadr x) (cadar x)))))) (cdr al)))
  226.             (not (vl-some '(lambda ( x ) (insiderec bp (mapcar '+ bp (list (caadr e) (cadadr e))) (mapcar '+ (car x) (list (* (- (caadr x) (caar x)) 0.5) (* (- (cadadr x) (cadar x)) 0.5))))) (cdr al)))
  227.           )
  228.           (progn
  229.             (vla-move (vlax-ename->vla-object (car e)) (vlax-3d-point (caddr e)) (vlax-3d-point bp))
  230.             (setq el (vl-remove-if '(lambda ( x ) (eq (car x) (car e))) el))
  231.             (cond
  232.               ( (process el (mapcar '+ bp (list (caadr e) 0.0)) (- dx (caadr e)) dy)
  233.                 (vl-cmdf "_.undo" "_b")
  234.                 (setq kb (1- kb))
  235.                 (main el (mapcar '+ bp (list (caadr e) 0.0)) (- dx (caadr e)) dy)
  236.               )
  237.               ( (process el (mapcar '+ bp (list 0.0 (cadadr e))) dx (- dy (cadadr e)))
  238.                 (vl-cmdf "_.undo" "_b")
  239.                 (setq kb (1- kb))
  240.                 (main el (mapcar '+ bp (list 0.0 (cadadr e))) dx (- dy (cadadr e)))
  241.               )
  242.               ( (process el (mapcar '+ bp (list (caadr e) (cadadr e))) (- dx (caadr e)) (- dy (cadadr e)))
  243.                 (vl-cmdf "_.undo" "_b")
  244.                 (setq kb (1- kb))
  245.                 (main el (mapcar '+ bp (list (caadr e) (cadadr e))) (- dx (caadr e)) (- dy (cadadr e)))
  246.               )
  247.               ( t el )
  248.             )
  249.           )
  250.           el
  251.         )
  252.       )
  253.       el
  254.     )
  255.   )
  256.  
  257.   (if (= 8 (logand 8 (getvar 'undoctl)))
  258.     (vla-endundomark adoc)
  259.   )
  260.   (setq cmde (getvar 'cmdecho))
  261.   (setvar 'cmdecho 0)
  262.   (setq ka 0)
  263.   (setq kb 0)
  264.   (if
  265.     (and
  266.       (not (prompt "\nSelect parts for nesting..."))
  267.       (setq ss (ssget "_:L"))
  268.       (not (prompt "\nPick boundary RECTANGLE..."))
  269.       (setq s (ssget "_+.:E:S" (list '(0 . "LWPOLYLINE") '(90 . 4) '(-4 . "&=") '(70 . 1) '(-4 . "<not") '(-4 . "<>") '(42 . 0.0) '(-4 . "not>"))))
  270.     )
  271.     (progn
  272.       (repeat (setq i (sslength ss))
  273.         (setq e (ssname ss (setq i (1- i))))
  274.         (vla-getboundingbox (vlax-ename->vla-object e) 'minpt 'maxpt)
  275.         (mapcar 'set '(minpt maxpt) (mapcar 'safearray-value (list minpt maxpt)))
  276.         (setq dx (- (car maxpt) (car minpt)))
  277.         (setq dy (- (cadr maxpt) (cadr minpt)))
  278.         (setq el (cons (list e (list dx dy) minpt) el))
  279.       )
  280.       (setq lw (ssname s 0))
  281.       (vla-getboundingbox (vlax-ename->vla-object lw) 'minpt 'maxpt)
  282.       (mapcar 'set '(minpt maxpt) (mapcar 'safearray-value (list minpt maxpt)))
  283.       (setq dx (- (car maxpt) (car minpt)))
  284.       (setq dy (- (cadr maxpt) (cadr minpt)))
  285.       (setq bp minpt)
  286.       (setq el (main el bp dx dy))
  287.       (while (and el (setq ll (car l)))
  288.         (setq l (cdr l))
  289.         (mapcar 'set '(bp dx dy) ll)
  290.         (setq el (main el bp dx dy))
  291.       )
  292.       (prompt "\nType \"UNDO\" ") (princ ka) (prompt " for back if you are using AutoCAD...")
  293.       (prompt "\nType \"UNDO\" ") (princ kb) (prompt " for back if you are using BricsCAD...")
  294.     )
  295.   )
  296.   (*error* nil)
  297. )
  298.  

Regards, M.R.
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on July 15, 2021, 09:53:13 AM
Marko, I tried your program, this is the result:
Title: Re: Automatic Nesting for lisp?
Post by: ribarm on July 15, 2021, 11:21:33 AM
Look Marc', there were many attempts for this problem for solution to be found, but all up to now, they were just attempts... I believe that you can get your example solved with my previously posted code and picked smaller rectangle... But that's all... When there are more rectangles that vary in sizes, the task complicate enourmously... I was able to write 2 more algorithms that were similar, but not for nesting - they are for packing in 2d and 3d... I can only say that when you code for this, you must not apply both 2d entities along with 3d ones - they have their geometry specific properties and although you can have 3d algorithm - it does not mean it can be applicable for all... There were some attempts in history called "guilotine cutting" - meaning that when you cut, you can make knife go only straight until piece is choped... Also there were some called non-guilotine where you can position pieces differently than straight, but this thing also complicates tasks... There is online solution finder for big outiline where you can put integer up to 1000 units in both directions and search for all equal smaller pieces where largest piece size is smaller integer than smaller size of outline... Algorithm is probably the best you can use, but the code is hidden from public... For testing here is the link : http://lagrange.ime.usp.br/~lobato/packing/run/index.php
You may also want to read about nesting problems more - there are some articles on www, but I didn't find an ALISP example(s)... So, if you have a time and you are interested in this problem, you can dedicate your time and code for solutions... But be informed that task although may look simple and easy, actually involves deeper understanding of basic geometry and high math skills... So good luck (what can I say different...)...
Title: Re: Automatic Nesting for lisp?
Post by: Marc'Antonio Alessi on July 15, 2021, 11:36:15 AM
Thanks for your long answer and for your time  :-), i don't think i will try i don't have the mathematical basis to do it.  :nerdyembarassed:
Title: Re: Automatic Nesting for lisp?
Post by: vink8023 on September 15, 2021, 10:15:03 PM
Reply to animated gif... Not 100% sure, but this is my simple version... Should work with imaginary rectangular bounding boxes like posted gif, but my version is using one single rectangle for entity where nesting is expected...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:nesting ( / *adoc* ss s bndr minp maxp w h i e eminp emaxp ew eh el x y bp ell elll )
  2.  
  3.  
  4.   (prompt "\nSelect nesting 2D entities...")
  5.   (setq ss (ssget "_:L"))
  6.   (prompt "\nPick boundary rectangle to nest to...")
  7.   (setq s (ssget "_+.:E:S" (list '(0 . "LWPOLYLINE") '(90 . 4) '(-4 . "<or") '(70 . 1) '(70 . 129) '(-4 . "or>") '(-4 . "<not") '(-4 . "<>") '(42 . 0.0) '(-4 . "not>"))))
  8.   (setq bndr (ssname s 0))
  9.   (vla-getboundingbox (vlax-ename->vla-object bndr) 'minp 'maxp)
  10.   (mapcar 'set '(minp maxp) (mapcar 'safearray-value (list minp maxp)))
  11.   (setq w (- (car maxp) (car minp)))
  12.   (setq h (- (cadr maxp) (cadr minp)))
  13.   (repeat (setq i (sslength ss))
  14.     (setq e (ssname ss (setq i (1- i))))
  15.     (vla-getboundingbox (vlax-ename->vla-object e) 'eminp 'emaxp)
  16.     (mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
  17.     (setq ew (- (car emaxp) (car eminp)))
  18.     (setq eh (- (cadr emaxp) (cadr eminp)))
  19.     (setq el (cons (list eminp ew eh e) el))
  20.   )
  21.   (setq el (vl-sort el '(lambda ( a b ) (if (equal (caddr a) (caddr b) 1e-3) (< (cadr a) (cadr b)) (< (caddr a) (caddr b))))))
  22.   (while
  23.     (and
  24.       (car el)
  25.       (<
  26.         (cond
  27.           ( (null x) (setq x 0.0 y 0.0) x )
  28.           ( (> (+ x (cadar el)) w)
  29.             (setq x 0.0)
  30.             (foreach e elll
  31.               (setq ell (vl-remove e ell))
  32.             )
  33.             (setq elll ell)
  34.             (vl-some
  35.              '(lambda ( e )
  36.                 (if (< (cadar el) (car e))
  37.                   (setq y (+ (cadr e) (caddr (caddr e))))
  38.                 )
  39.               )
  40.               (reverse ell)
  41.             )
  42.             x
  43.           )
  44.           ( t
  45.             (if
  46.               (not
  47.                 (vl-some
  48.                  '(lambda ( e )
  49.                     (if (< (+ x (cadar el)) (car e))
  50.                       (setq y (+ (cadr e) (caddr (caddr e))))
  51.                     )
  52.                   )
  53.                   (reverse ell)
  54.                 )
  55.               )
  56.               (vl-some
  57.                '(lambda ( e )
  58.                   (if (or (< (+ x (cadar el)) (car e)) (< (+ x 1e-3) (car e)))
  59.                     (setq y (+ (cadr e) (caddr (caddr e))))
  60.                   )
  61.                 )
  62.                 (vl-sort ell '(lambda ( a b ) (> (car a) (car b))))
  63.               )
  64.             )
  65.             x
  66.           )
  67.         )
  68.         w
  69.       )
  70.       (or (< (+ y (caddar el)) h) (equal (+ y (caddar el)) h 1e-3))
  71.     )
  72.     (if (= x 0.0)
  73.       (setq bp (list (car minp) (+ y (cadr minp)) 0.0))
  74.       (setq bp (list (+ x (car minp)) (+ y (cadr minp)) 0.0))
  75.     )
  76.     (setq x (+ x (cadar el)))
  77.     (vla-move (vlax-ename->vla-object (cadddr (car el))) (vlax-3d-point (caar el)) (vlax-3d-point bp))
  78.     (setq ell (cons (list x y (car el)) ell))
  79.     (setq el (cdr el))
  80.   )
  81.   (vla-endundomark *adoc*)
  82.   (princ)
  83. )
  84.  

Regards, M.R.

How to modify the program to add spacing between parts and between materials and parts?
Title: Re: Automatic Nesting for lisp?
Post by: BIGAL on September 16, 2021, 08:45:41 PM
The simplest way is draw a dummy line say from the corners for the gap required, should work, NOT TESTED !
Title: Re: Automatic Nesting for lisp?
Post by: vink8023 on September 16, 2021, 08:56:26 PM
This is exactly what I wanted
Title: Re: Automatic Nesting for lisp?
Post by: vink8023 on September 16, 2021, 09:12:12 PM
Reply to animated gif... Not 100% sure, but this is my simple version... Should work with imaginary rectangular bounding boxes like posted gif, but my version is using one single rectangle for entity where nesting is expected...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:nesting ( / *adoc* ss s bndr minp maxp w h i e eminp emaxp ew eh el x y bp ell elll )
  2.  
  3.  
  4.   (prompt "\nSelect nesting 2D entities...")
  5.   (setq ss (ssget "_:L"))
  6.   (prompt "\nPick boundary rectangle to nest to...")
  7.   (setq s (ssget "_+.:E:S" (list '(0 . "LWPOLYLINE") '(90 . 4) '(-4 . "<or") '(70 . 1) '(70 . 129) '(-4 . "or>") '(-4 . "<not") '(-4 . "<>") '(42 . 0.0) '(-4 . "not>"))))
  8.   (setq bndr (ssname s 0))
  9.   (vla-getboundingbox (vlax-ename->vla-object bndr) 'minp 'maxp)
  10.   (mapcar 'set '(minp maxp) (mapcar 'safearray-value (list minp maxp)))
  11.   (setq w (- (car maxp) (car minp)))
  12.   (setq h (- (cadr maxp) (cadr minp)))
  13.   (repeat (setq i (sslength ss))
  14.     (setq e (ssname ss (setq i (1- i))))
  15.     (vla-getboundingbox (vlax-ename->vla-object e) 'eminp 'emaxp)
  16.     (mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
  17.     (setq ew (- (car emaxp) (car eminp)))
  18.     (setq eh (- (cadr emaxp) (cadr eminp)))
  19.     (setq el (cons (list eminp ew eh e) el))
  20.   )
  21.   (setq el (vl-sort el '(lambda ( a b ) (if (equal (caddr a) (caddr b) 1e-3) (< (cadr a) (cadr b)) (< (caddr a) (caddr b))))))
  22.   (while
  23.     (and
  24.       (car el)
  25.       (<
  26.         (cond
  27.           ( (null x) (setq x 0.0 y 0.0) x )
  28.           ( (> (+ x (cadar el)) w)
  29.             (setq x 0.0)
  30.             (foreach e elll
  31.               (setq ell (vl-remove e ell))
  32.             )
  33.             (setq elll ell)
  34.             (vl-some
  35.              '(lambda ( e )
  36.                 (if (< (cadar el) (car e))
  37.                   (setq y (+ (cadr e) (caddr (caddr e))))
  38.                 )
  39.               )
  40.               (reverse ell)
  41.             )
  42.             x
  43.           )
  44.           ( t
  45.             (if
  46.               (not
  47.                 (vl-some
  48.                  '(lambda ( e )
  49.                     (if (< (+ x (cadar el)) (car e))
  50.                       (setq y (+ (cadr e) (caddr (caddr e))))
  51.                     )
  52.                   )
  53.                   (reverse ell)
  54.                 )
  55.               )
  56.               (vl-some
  57.                '(lambda ( e )
  58.                   (if (or (< (+ x (cadar el)) (car e)) (< (+ x 1e-3) (car e)))
  59.                     (setq y (+ (cadr e) (caddr (caddr e))))
  60.                   )
  61.                 )
  62.                 (vl-sort ell '(lambda ( a b ) (> (car a) (car b))))
  63.               )
  64.             )
  65.             x
  66.           )
  67.         )
  68.         w
  69.       )
  70.       (or (< (+ y (caddar el)) h) (equal (+ y (caddar el)) h 1e-3))
  71.     )
  72.     (if (= x 0.0)
  73.       (setq bp (list (car minp) (+ y (cadr minp)) 0.0))
  74.       (setq bp (list (+ x (car minp)) (+ y (cadr minp)) 0.0))
  75.     )
  76.     (setq x (+ x (cadar el)))
  77.     (vla-move (vlax-ename->vla-object (cadddr (car el))) (vlax-3d-point (caar el)) (vlax-3d-point bp))
  78.     (setq ell (cons (list x y (car el)) ell))
  79.     (setq el (cdr el))
  80.   )
  81.   (vla-endundomark *adoc*)
  82.   (princ)
  83. )
  84.  

Regards, M.R.


 
Nesting of parts to add spacing
Title: Re: Automatic Nesting for lisp?
Post by: vink8023 on September 16, 2021, 09:14:40 PM
How to use your code to write a program that looks like a GIF image