Minor tweak for nesting objects in polyline

Minor tweak for nesting objects in polyline

Anonymous
Not applicable
3,208 Views
11 Replies
Message 1 of 12

Minor tweak for nesting objects in polyline

Anonymous
Not applicable

Hello all,

 

I have some code here and it works great but its not quite there to where I need it to be. 

I think I can make it work but it I know it can be done a lot better.

What it does is nest all my panels on a sheet, where I am having troubles is getting the code to keep all my panels a 1/2" apart (for the tooling). I work with wood so the grain direction is a huge deal which means the panels can not be rotated.

Like I said, I could probable do it but I know there is a better way than to:

Offset all the objects to the outside 1/2"

Delete the source of the previous offset 

Run the nesting code

Offset all the objects to the inside 1/2"

Delete the source of the previous offset

 

I just don't understand this code yet. 

Can someone explain how to modify the spacing between objects in this code.

or even help me do this. 

I would like to lean too thought 🙂

 

Thanks!

 

 

(defun c:nesting ( / *adoc* ss s bndr minp maxp w h i e eminp emaxp ew eh el x y bp ell elll )
 
  (vl-load-com)
 
  (vla-startundomark (setq *adoc* (vla-get-activedocument (vlax-get-acad-object))))
  (prompt "\nSelect nesting 2D entities...")
  (setq ss (ssget "_:L"))
  (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>"))))
  (setq bndr (ssname s 0))
  (vla-getboundingbox (vlax-ename->vla-object bndr) 'minp 'maxp)
  (mapcar 'set '(minp maxp) (mapcar 'safearray-value (list minp maxp)))
  (setq w (- (car maxp) (car minp)))
  (setq h (- (cadr maxp) (cadr minp)))
  (repeat (setq i (sslength ss))
    (setq e (ssname ss (setq i (1- i))))
    (vla-getboundingbox (vlax-ename->vla-object e) 'eminp 'emaxp)
    (mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
    (setq ew (- (car emaxp) (car eminp)))
    (setq eh (- (cadr emaxp) (cadr eminp)))
    (setq el (cons (list eminp ew eh e) el))
  )
  (setq el (vl-sort el '(lambda ( a b ) (if (equal (caddr a) (caddr b) 1e-3) (< (cadr a) (cadr b)) (< (caddr a) (caddr b))))))
  (while
    (and 
      (car el)
      (< 
        (cond 
          ( (null x) (setq x 1 y 1) x )
          ( (> (+ x (cadar el)) w) 
            (setq x 1)
            (foreach e elll
              (setq ell (vl-remove e ell))
            )
            (setq elll ell)
            (vl-some 
             '(lambda ( e ) 
                (if (< (cadar el) (car e))
                  (setq y (+ (cadr e) (caddr (caddr e))))
                )
              )
              (reverse ell)
            )
            x
          )
          ( t
            (if
              (not
                (vl-some 
                 '(lambda ( e ) 
                    (if (< (+ x (cadar el)) (car e))
                      (setq y (+ (cadr e) (caddr (caddr e))))
                    )
                  )
                  (reverse ell)
                )
              )
              (vl-some
               '(lambda ( e )
                  (if (or (< (+ x (cadar el)) (car e)) (< (+ x 1e-3) (car e)))
                    (setq y (+ (cadr e) (caddr (caddr e))))
                  )
                )
                (vl-sort ell '(lambda ( a b ) (> (car a) (car b))))
              )
            )
            x
          )
        )
        w
      )
      (or (< (+ y (caddar el)) h) (equal (+ y (caddar el)) h 1e-3))
    )
    (if (= x 0.0)
      (setq bp (list (car minp) (+ y (cadr minp)) 0.0))
      (setq bp (list (+ x (car minp)) (+ y (cadr minp)) 0.0))
    )
    (setq x (+ x (cadar el)))
    (vla-move (vlax-ename->vla-object (cadddr (car el))) (vlax-3d-point (caar el)) (vlax-3d-point bp))
    (setq ell (cons (list x y (car el)) ell))
    (setq el (cdr el))
  )
  (vla-endundomark *adoc*)
  (princ)
)
0 Likes
Accepted solutions (1)
3,209 Views
11 Replies
Replies (11)
Message 2 of 12

Anonymous
Not applicable

Here is a drawing to give an idea of what is happening and what needs to be done.

0 Likes
Message 3 of 12

ВeekeeCZ
Consultant
Consultant
Accepted solution

Add these 2 lines and somehow set the bfr variable before.

 

    (mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
    (setq eminp (mapcar '- eminp (list bfr bfr)))
    (setq emaxp (mapcar '+ emaxp (list bfr bfr)))
    (setq ew (- (car emaxp) (car eminp)))

Just at first glance... it looks like it makes a bounding box of each shape and then works with that. So what I did is enlarging the bounding boxes by a buffer.

0 Likes
Message 4 of 12

Anonymous
Not applicable

Awesome, thanks for the help! 

Does exactly what I need!

0 Likes
Message 5 of 12

ahsattarian3
Enthusiast
Enthusiast

This works on several sheets  :

 

 

 

(defun c:nest ()
(prompt "\n Select nesting 2D entities : ")
(setq ss1 (ssget "_:L"))
(prompt "\n Pick boundary rectangle to nest to :")
(setq filter (list '(0 . "lwpolyline") '(90 . 4) '(-4 . "<or") '(70 . 1) '(70 . 129) '(-4 . "or>") '(-4 . "<not") '(-4 . "<>") '(42 . 0.0)
'(-4 . "not>"))
)
;;(setq ss2 (ssget "_+.:E:S" filter))
(setq ss2 (ssget filter))
(setq el nil)
(setq n1 (sslength ss1))
(setq k1 -1)
(repeat n1
(setq k1 (1+ k1))
(setq s1 (ssname ss1 k1))
(setq obj1 (vlax-ename->vla-object s1))
(vla-getboundingbox obj1 'eminp 'emaxp)
(mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
(setq ew (- (car emaxp) (car eminp)))
(setq eh (- (cadr emaxp) (cadr eminp)))
(cond
((> ew eh)
(setq po (mapcar '/ (mapcar '+ eminp emaxp) (list 2.0 2.0 2.0)))
(vla-rotate obj1 (vlax-3d-point po) (* 0.5 pi))
(vla-getboundingbox obj1 'eminp 'emaxp)
(mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
(setq ew (- (car emaxp) (car eminp)))
(setq eh (- (cadr emaxp) (cadr eminp)))
)
)
(setq el (cons (list eminp ew eh s1) el))
)
(setq el (vl-sort el
'(lambda (a b)
(if (equal (caddr a) (caddr b) 1e-3)
(< (cadr a) (cadr b))
(< (caddr a) (caddr b))
)
)
)
)
(setq n2 (sslength ss2))
(setq k2 -1)
(repeat n2
(setq k2 (1+ k2))
(setq s2 (ssname ss2 k2))
(setq obj2 (vlax-ename->vla-object s2))
(vla-getboundingbox obj2 'minp 'maxp)
(mapcar 'set '(minp maxp) (mapcar 'safearray-value (list minp maxp)))
(setq w (- (car maxp) (car minp)))
(setq h (- (cadr maxp) (cadr minp)))
(setq x nil)
(setq y nil)
(setq yn nil)
(setq ell nil)
(setq elll nil)
(while
(and
(car el)
(cond
((null x) (setq x 0.0) (setq y 0.0) (setq f 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) (cond ((< (cadar el) (+ (car e) 1e-3)) (setq yn (+ (cadr e) (caddr (caddr e)))))))
(reverse ell)
)
(cond ((> yn y) (setq y yn)))
(setq f x)
)
(t
(if
(not
(vl-some '(lambda (e) (cond ((< (+ x (cadar el)) (+ (car e) 1e-3)) (setq yn (+ (cadr e) (caddr (caddr e)))))))
(reverse ell)
)
)
(vl-some
'(lambda (e)
(cond ((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))))
)
)
(cond ((> yn y) (setq y yn)))
(setq f x)
)
)
(< f w)
(or (< (+ y (caddar el)) h) (equal (+ y (caddar el)) h 1e-3))
)
(if (= x 0.0)
(setq bp (list (car minp) (+ y (cadr minp)) 0.0))
(setq bp (list (+ x (car minp)) (+ y (cadr minp)) 0.0))
)
(setq x (+ x (cadar el)))
(vla-move (vlax-ename->vla-object (cadddr (car el))) (vlax-3d-point (caar el)) (vlax-3d-point bp))
(setq ell (cons (list x y (car el)) ell))
(setq el (cdr el))
)
)
(princ)
)

 

 

 

Message 6 of 12

Anonymous
Not applicable

Mr ahsattarian, you code works very well, my compliments. 

Could you change this code to set rotary to 0 degree and set 5mm distance between parts? 

If it comes to rotary - I have changed:

(vla-rotate obj1 (vlax-3d-point po) (* 0.5 pi)) into (vla-rotate obj1 (vlax-3d-point po) (* 0 pi))

but it does not work corretly right now. Some pieces overlap.

 

Nowy obraz mapy bitowej (2).png

Many thanks in advance

0 Likes
Message 7 of 12

Sea-Haven
Mentor
Mentor

This portion rotates 90 deg, remove, but may not help your other problems

(cond
((> ew eh)
(setq po (mapcar '/ (mapcar '+ eminp emaxp) (list 2.0 2.0 2.0)))
(vla-rotate obj1 (vlax-3d-point po) (* 0.5 pi))
(vla-getboundingbox obj1 'eminp 'emaxp)
(mapcar 'set '(eminp emaxp) (mapcar 'safearray-value (list eminp emaxp)))
(setq ew (- (car emaxp) (car eminp)))
(setq eh (- (cadr emaxp) (cadr eminp)))
)
)

 

 

0 Likes
Message 8 of 12

bradley_minger93J6Y
Participant
Participant

Can you tell me how to set the bfr variable or share the code you used to get it to work? I am running your original code (without any spacing between nested objects) and it works, but I can't figure out how to get this to run.

0 Likes
Message 9 of 12

ckobielnik
Explorer
Explorer

I wanted to revisit this particular thread. I currently am wondering (really just seeing if this is possible), to take let's say, an irregular [non-rectangular part], create a boundary, use said boundary to generate a part, and somehow convert that portion to a region that conforms to the contour of the shape. is it possible to make a bounding box conform to just the contours of that shape? or am I thinking about this all wrong? I'd like to make something like this to make quoting jobs faster and more accurate than having to go all the way to my nesting software (which is a dinosaur and prone to multiple lock-ups and freezing in the middle of my work, they don't spend money to make money....) Any help in this matter would be great. I'm trying to utilize LT and Full autocad for this. I was pleasantly surprised to see lisp integration with LT so I'm taking full advantage of this. 

0 Likes
Message 10 of 12

cadffm
Consultant
Consultant

Hi,

 

idea: Create sample to show the task - like the .dwg above. Show what you have, your steps and the result.

Not every one understood what you are talking about ( 🙂 ) ,

 

Pretty sure wrong, but it showing a way to explain your task - step by step, colors and text..

cadffm_1-1737558687492.png

 

 

 

Edit my sample or create your own.

Sebastian

0 Likes
Message 11 of 12

ckobielnik
Explorer
Explorer

I hope I explained this better with the attached file. It's just a question of would it be possible to do purely in LISP? 

0 Likes
Message 12 of 12

cadffm
Consultant
Consultant

Okay, I really misunderstood that. So basically it's about exactly the same topic as above.

Nesting is a completely different topic
and solutions are described independently of CAD and Lisp on the internet: That means there is
an incredible amount of information and different approaches to it.

Lots of reading material, you just have to implement it - at least as far as possible.

It can't be 100% perfect, but >90% isn't bad either. There is certainly room for improvement.

If it's a large number of units and expensive material:

I would use a ready-made tool, 99% of the time it would be done outside of ACAD, but it depends on the result.

I am out.

Sebastian

0 Likes