View Full Version : Cutting Strategy Routine
a1harps
24th Dec 2004, 08:31 pm
I have no idea how difficult it would be, but I often wish I had a lisp
or a spread sheet program would caculate the most efficient way
to get a series of rectangles and squares out of a rectangle 48 units
wide by 96 units tall (48"x 96" is the dimention of a standard sheet of U.S. plywood).
The best scenario for me would be being able to input a list of dimentions from the command line(Acad 2000) such as 22.25,33.625-
12.375,55.5625-33.3125,44.875 etc. Autocad would then draw the required number of 48"x 96" rectangles and place the inputed rectangles
and squares within the 48"x96" rectangles in an arrangement that would give the best yield of square inches of parts with the least amount unused area (waste). An option of rotating the rectangles 90 degrees (or not) would be helpfull because some jobs require the x and y coordinates of the parts list to allign with the 48" x 96" rectangles x any y coordinates, and some do not require that.
The other scenario would be for me to hand draw the rectangles representing the parts and then Autocad(2000) would arrange them
within the borders of 48"x96" rectangles without overlapping and in an
arrangement that would give the best yield of square inches and
the least amount of wasted square inches
Because list programing is beyond my skill at this point, I do not know
if this is possible or how difficult it would be.
Frank
hyposmurf
25th Dec 2004, 12:00 pm
You could draw a rectangle and then use a offset distance to draw many smaller rectangles that fit within this rectangle.Youre also parts as if youre going to be using these parts numerous times why not create blocks?Have I understood you correctly?
David Bethel
25th Dec 2004, 03:59 pm
Frank,
Nesting programs are very interesting to do and very very complicated to do correctly. You also need very steadfast rules. For example, is there a minimal distance between the objects, can the objects use the edge of the material, are there machine holding clamps that must be accounted for.
For a manual sheet metal shearing operation, then all clearances could be 0. For a laser or plasma cutting, then it's a maybe. For a millwork router, it's a must.
The alogritims are fairly simple, but can get very in depth in the tree department.
I'd post a couple that I have done, but they are covered by NDAs -David
a1harps
25th Dec 2004, 10:20 pm
Hyposmurf,
Thank you for the reply. The problem isnt that I cant draw the 48"x96'
rectangle and then manually figure out how to most efficently get
the smaller ones to fit within it, the problem is that it is time consuming
and time is money.
David, thank you for your reply. Your obsevations are correct.
I will deal with the "loss of material" by adding the waste (in my case
usually .125" ) to the sizes I input ie: If i need a part size to net
24.25x 32.75 I will input it as 24.375x32.875 ( This will actually double
the actuall "kerf" for parts that do not come off the outside edge of
the sheet but if I had a program to even do it that accurately it
be close enough and save me a lot of time.
So then to answer your post, there would be a zero dimention between
parts and they can be right on the edge of the material.
The other rule of importance to my application would be an option
to rotate the parts 90 degrees(if necessary for more efficient yield) or not to rotate them to deal with the variable that some material has a "grain" direction and some material does not. The xand y coordinates of the parts list would allways be entered to be oriented correctly when
the option not to rotate has been selected.
I look forward to your postings
Frank
David Bethel
26th Dec 2004, 03:48 pm
Frank,
The next part of the equation is whether or not the cutting process is totally free form or a shear / overrun cut.
Can the machine actually work this example:
http://www.davidbethel.com/cadtutor/cut.gif
This scenario is impossible with shearing operation. 2, 3, & 4 would have to be glued back together <g>
Also it would next to impossible with a circular sawing cut. Laser / Plasma could do it.
As to data input, I would use an ASCII text file
test.dat
(setq data '(
("pn1" 24.375 30.375 0)
("pn2" 12.375 24.375 1)
("pn3" 10.625 22.875 0)
))
With the sequence:
string_part_number x_axis y_axis boolean_rotate0=false/1=true
space delimited, Autolisp list format.
There would be a need to reserve at least 1 character in the part number for internal program use. I normally have it so that your part number cannot use "0" ( zero ) for the first letter.
That way I could do this:
(if (= (last ("pn2" 12.375 24.375 1)) 1)
(setq data (append data (list ("0pn2" 24.375 12.375 1))))
-David
PS: If you do get a finished program up an running, it probably has some monetary value to someone, so I wouldn't post it in it's entirety. You never know, someone may offer you big bucks for it!!!
a1harps
26th Dec 2004, 06:34 pm
Wow David,
You nailed the last two items I ommited in an effort to simplify.
The need to label the parts with a number, and internal cuts.
I wanted to see if anything could be managed and I of course knew
if a computer figured out a strategy with the least waste it wouldnt
arrange the parts to be sawn with a circular saw :)
On occasion I will make a stopped cut and finish with a hand saw
or a jig saw to avoid a 40 mile trip to my hardwood ply. dealer to buy
an $89.00 sheet for cutting one part.
For the most part, the sheets have to be sawn either all the way through
the y axis or the x axis and then further sawn.
As I feared, I will interpret the last part of your post as meaning
this type of routine would be a large undertaking that a person wouldnt
likely give away.
I do appreciate your time spent on this but I honestly couldnt write a
lisp that would draw a one inch line in positive x at this point.
As you know, a CNC router could also cut the scenario you posted
but I dont have one.
I saw a lot of custom lisp routines being posted to help people with
special applications and thought it wouldnt hurt to ask :)
I will put the info you you posted in my files for future days.
Thankyou for your work!
Frank
David Bethel
26th Dec 2004, 08:29 pm
Frank,
The first one of these I did was on an old old sheet metal punch press. ( Wedomatic I think called ) It had 52 punches of various sizes and shapes. So basically we had the program pick the punch, calculate the offset so that the cut edge was in the proper position, and issue a down mode ( punch ). All virtual. We had a machine that could convert DXF formats into CNC ticker tape. Put the proper sheet of metal on the machine table bed, clamp it down The machine moved the sheet of metal around so that the punch was in the proper and wham wham wham, leaving a small piece at each corner that was then the last process before the blank was manually pull from the table. It was in the late '80s ( ACAD 2.62 ) and was a blast.
Seeing how yours is basically a free form style, programming it would be a lot easier. 1 gotcha is the 0.125" blade width.
Try this scenario:
48" material width
(1) piece 23.875, (1) piece 24.000 - all finished sizes. Technically they can be cut from 1 blank. By including the blade width in your data, it would pretty well preclude this type of cut. I would suggest letting the program calculate the blade stuff and use the actual finished piece size. Who knows, you may have to go to a 3\16" blade someday or someone makes a 1\16" diamond edged knife. That way the program could easily be modified to accept the new blade parameter.
-David
a1harps
26th Dec 2004, 09:22 pm
David,
I had anticipated that risk (missing an optimum yield by doubling the
tool path) but I figured on doing some of the thinking myself.
Better idea to let the computer do as much as possible :)
So then the rules at this point:
The sheet must be cut completely through the X or Y axis before
secondary cuttings can be made. This rule applies to secondary cuttings also.
There are no clamps or other obstacles for the routine to consider.
The routine will calculate a variable waste amount on the edges of the material and between each part.
A variable to select whether or not the parts X and Y axises can
be interchanged for greater yield to deal with materials that have
or do not have a "grain" direction.
The "parts" will be givin numbers as they are entered and the routine
will indicate what the numbers are in the finished product.
The only other thing that comes to mind right now is that it
would be of use to have a variable to have it layed out as though
it was going to be cut by laser because sometimes it is worth it timewise
to make a few "stopped" cuts on the saw when the material is costing
nearly $100.00 dollars a sheet. However I would be thankfull for
a routine of any design that you can create.
Thanks for the help David and let me now if I forgot any other rules.
Frank
David Bethel
26th Dec 2004, 10:40 pm
Frank,
For simplisty in development, it is better to focus on either free style or shear alone. I choose shear.
Cut and paste this to an new pure ASCII text file named test1.dat
(setq data '(
("pn1" 24.375 30.375 0)
("pn2" 12.375 24.375 1)
("pn3" 10.625 22.875 0)
))
Save this as new.lsp
;================================================= ======================
; New.Lsp Dec 22, 2004
; Edit Name And SubRoutine Prefix nw_ To Ensure Unique Definitions
;================== Start Program ======================================
(princ "\nCopyright (C) 2004, Fabricated Designs, Inc.")
(princ "\nLoading New v1.0 ")
(setq nw_ nil lsp_file "New")
;================== Macros =============================================
(defun PDot ()(princ "."))
(PDot);++++++++++++ Set Modes & Error ++++++++++++++++++++++++++++++++++
(defun nw_smd ()
(SetUndo)
(setq oldlay (getvar "CLAYER")
olderr *error*
*error* (lambda (e)
(while (> (getvar "CMDACTIVE") 0)
(command))
(and (/= e "quit / exit abort")
(princ (strcat "\nError: *** " e " *** ")))
(and (= (logand (getvar "UNDOCTL") 8) 8)
(command "_.UNDO" "_END" "_.U"))
(nw_rmd))
nw_var '(("CMDECHO" . 0) ("MENUECHO" . 0)
("MENUCTL" . 0) ("MACROTRACE" . 0)
("OSMODE" . 0) ("SORTENTS" . 119)
("MODEMACRO" . ".")
("BLIPMODE" . 0) ("EXPERT" . 0)
("SNAPMODE" . 1) ("PLINEWID" . 0)
("ORTHOMODE" . 1) ("GRIDMODE" . 0)
("ELEVATION" . 0) ("THICKNESS" . 0)
("FILEDIA" . 0) ("FILLMODE" . 0)
("SPLFRAME" . 0) ("UNITMODE" . 0)
("TEXTEVAL" . 0) ("ATTDIA" . 0)
("AFLAGS" . 0) ("ATTREQ" . 1)
("ATTMODE" . 1) ("UCSICON" . 1)
("HIGHLIGHT" . 1) ("REGENMODE" . 1)
("COORDS" . 2) ("DRAGMODE" . 2)
("DIMZIN" . 1) ("PDMODE" . 0)
("CECOLOR" . "BYLAYER")
("CELTYPE" . "BYLAYER")))
(foreach v nw_var
(and (getvar (car v))
(setq nw_rst (cons (cons (car v) (getvar (car v))) nw_rst))
(setvar (car v) (cdr v))))
(princ (strcat (getvar "PLATFORM") " Release " (ver)
" - Material Nesting Development Routine ....\n"))
(princ))
(PDot);++++++++++++ Return Modes & Error +++++++++++++++++++++++++++++++
(defun nw_rmd ()
(SetLayer oldlay)
(setq *error* olderr)
(foreach v nw_rst (setvar (car v) (cdr v)))
(command "_.UNDO" "_END")
(prin1))
(PDot);++++++++++++ Set And Start An Undo Group ++++++++++++++++++++++++
(defun SetUndo ()
(and (zerop (getvar "UNDOCTL"))
(command "_.UNDO" "_ALL"))
(and (= (logand (getvar "UNDOCTL") 2) 2)
(command "_.UNDO" "_CONTROL" "_ALL"))
(and (= (logand (getvar "UNDOCTL") 8) 8)
(command "_.UNDO" "_END"))
(command "_.UNDO" "_GROUP"))
(PDot);++++++++++++ Make Layer Current +++++++++++++++++++++++++++++++++
(defun SetLayer (name / ldef flag)
(command "_.LAYER")
(if (not (tblsearch "LAYER" name))
(command "_Make" name)
(progn
(setq ldef (tblsearch "LAYER" name)
flag (cdr (assoc 70 ldef)))
(and (= (logand flag 1) 1)
(command "_Thaw" name))
(and (minusp (cdr (assoc 62 ldef)))
(command "_On" name))
(and (= (logand flag 4) 4)
(command "_Unlock" name))
(and (= (logand flag 16) 16)
(princ "\nCannot Set To XRef Dependent Layer")
(quit))
(command "_Set" name)))
(command "")
name)
(PDot);************ Main Program ***************************************
(defun nw_ (/ olderr oldlay nw_var nw_rst x y w file)
(nw_smd)
; (*debug* 32 "nw_")
(initget 6)
(setq x (getdist "\nMaterial X Axis Size <96>: "))
(and (not x)
(setq x 96.))
(initget 6)
(setq y (getdist "\nMaterial Y Axis Size <48>: "))
(and (not y)
(setq y 48.))
(initget 6)
(setq w (getdist "\nBlade Thickness <0.125>: "))
(and (not w)
(setq w 0.125))
(while (not file)
(setq file (getfiled "ASCII DATA File To Import" "/acad/" "dat" 2)))
(load file)
; (*break*)
; (*debug* 0 "nw_")
(nw_rmd))
(PDot);************ Load Program ***************************************
(defun C:NW () (nw_))
(if nw_ (princ "\nNew Loaded\n"))
(prin1)
;|================== End Program =======================================
At the command line
Command: (load "New")
Command: NW
It is a start. -David
David Bethel
27th Dec 2004, 03:01 pm
Okay, seeing how this is a teaching forum, lets develop this in steps, if it is okay with CadTutor.
Step 0 was the AutoLisp and Data file templates.
Step1 was to get the user input:
(defun step1 ()
(initget 6)
(setq x (getdist "\nMaterial X Axis Size <96>: "))
(and (not x)
(setq x 96.))
(initget 6)
(setq y (getdist "\nMaterial Y Axis Size <48>: "))
(and (not y)
(setq y 48.))
(initget 6)
(setq w (getdist "\nBlade Thickness <0.125>: "))
(and (not w)
(setq w 0.125))
(while (not file)
(setq file (getfiled "ASCII DATA File To Import" "" "dat" 2)))
(list x y w file))
Step2 will be to load and verify tha data:
(defun step2 (file / i pn xv yv rt)
(princ "\nLoading Data File...\n")
(setq i 0)
(cond ((not (load file))
(alert "Data File Invalid")
(exit))
((not data)
(alert "Data File Empty")
(exit))
((/= (type data) 'LIST)
(alert "Improper Data Format")
(exit))
((foreach a data
(cond ((/= (type a) 'LIST)
(alert (strcat "Atom nth " (rtos i 2 0) " Invalid"))
(exit))
((/= (length a) 4)
(alert (strcat "Atom nth " (rtos i 2 0) " Invalid"))
(exit)))
(setq pn (nth 0 a)
xv (nth 1 a)
yv (nth 2 a)
rt (nth 3 a))
(cond ((or (/= (type pn) 'STR)
(= (substr pn 1 1) "0"))
(alert (strcat "Atom nth " (rtos i 2 0) " Part Number Invalid"))
(exit))
((not (numberp xv))
(alert (strcat "Atom nth " (rtos i 2 0) " X Value Invalid"))
(exit))
((not (numberp yv))
(alert (strcat "Atom nth " (rtos i 2 0) " Y Value Invalid"))
(exit))
((not (or (= rt 1)
(= rt 0)))
(alert (strcat "Atom nth " (rtos i 2 0) " Rotation Value Invalid"))
(exit)))
(setq i (1+ i)))))
(length data))
We will update the main program as it evolves:
(defun nw_ (/ olderr oldlay nw_var nw_rst x y w file)
(nw_smd)
(trace step1 step2)
;;;Get USER INPUT
(step1)
;;;LOAD & VERIFY DATA
(step2 file)
(nw_rmd))
I prefer to have each subroutine return a value. It can prove helpful in debugging the program. Also the (trace) function helps with this as well.
I also choose to exit the program when bad data is encountered. Having to try a correct the stuff usually isn't worth the effort. Also, you may want to run the same data file time and again during production work. So I force the user to fix the data file. -David
a1harps
27th Dec 2004, 04:44 pm
David
I can only get as far as step 2. You said you choose to exit when bad
data is encountered so I looked at the data file and but I cant tell if
anything is amiss.
After initiating the Autolisp I answer the three queries and then
open the data file... after that the Autolisp ends and nothing is
drawn on screen. Below you will find pasted the last content of the
command line when the Autolisp terminated.
Blade Thickness <0.125>:
Regenerating model.
_.UNDO Enter the number of operations to undo or
[Auto/Control/BEgin/End/Mark/Back] <1>: _END
Frank
David Bethel
27th Dec 2004, 05:25 pm
Frank,
At the command line
Command: !data
and you should see that the data has been read and stored in AutoLisp. We will manipulate the data further as we proceed. -David
Also, try:
SETVAR
CMDECHO
0
It will get rid of the command echos
a1harps
27th Dec 2004, 05:55 pm
David,
I changed the variable in CMDECHO to 0.
I took the risk of changing what I think are the quantities in
the data template to whole numbers.
Example:
I changed- ("pn1" 24.375 30.375 0)
to this- ("pn1" 24.375 30.375 2)
I entered !data at the command line and the contents of test1.dat were displayed.
I cant seem to go any further as the Autolisp still terminates after
the query for the data file ( is this what you refer to as a command echo?)
Frank
David Bethel
27th Dec 2004, 05:58 pm
Frank,
The last atom is for rotation - 0 or 1 only.
Quantites aren't in equation, so each peice will have to be indvidually inputted.
The program is along way for drawing anything yet. -David
a1harps
27th Dec 2004, 06:07 pm
David,
Ok, I think you are saying things are as they should be from
reading my description of things on my end.
Holding Horses In Oregon
-Frank
David Bethel
27th Dec 2004, 07:05 pm
Because this is a program that reads external data in which the programmer has no control over, all data should be verified. I gave it a minimum required cut of 0.125"
Step3 - Verify the sizes are smaller than the sheet
(defun step3 (/ pn xv yv rt)
(princ "\nVerifing Part Sizes...\n")
(foreach a data
(setq pn (nth 0 a)
xv (nth 1 a)
yv (nth 2 a)
rt (nth 3 a))
(if (= rt 1)
(setq rot T))
(cond ((< xv 0.125)
(alert (strcat "Part Number " pn " X Value Too Small"))
(exit))
((< yv 0.125)
(alert (strcat "Part Number " pn " Y Value Too Small"))
(exit)))
(if (= rt 0)
(cond ((> xv x)
(alert (strcat "Part Number " pn " X Value Too Large"))
(exit))
((> yv y)
(alert (strcat "Part Number " pn " Y Value Too Large"))
(exit)))
(cond ((and (<= xv x)
(> yv y))
(alert (strcat "Part Number " pn " Y Value Too Large"))
(exit))
((and (<= yv y)
(> xv x))
(alert (strcat "Part Number " pn " X Value Too Large"))
(exit))
((and (<= xv x)
(<= yv y)))
(T ;;;PART MUST BE ROTATED
(setq data (subst (list pn yv xv 0) a data))))))
rot)
-David
a1harps
27th Dec 2004, 07:57 pm
I understand why that is necessary.
-Frank
David Bethel
28th Dec 2004, 05:58 pm
Step4 is proving more and more of a challange.
Meanwhile we need a couple internal subroutines for finding the biggest peice that will come out of a specifed size.
(defun useage (x y xv yv)
(- 1 (/ (- (* x y) (* xv yv)) (float (* x y)))))
(defun findmax (l x y / pc tmp)
(setq pc 0)
(foreach a l
(setq pn (nth 0 a)
xv (nth 1 a)
yv (nth 2 a))
(if (and (> (setq tmp (useage x y xv yv)) pc)
(<= xv x)
(<= yv y))
(setq pc tmp part pn)))
part)
Still thinking on a simple alogrithim for the main engine.......
-David
a1harps
28th Dec 2004, 06:03 pm
Thank you for the update David,
Meanwhile, I am reading my textbook on Autolisp to hopefully
get some understanding of what makes it all tick.
-Frank
David Bethel
4th Jan 2005, 03:07 pm
Frank,
I haven't forgotten about you. I've been down with a stomach flu for the last few days and trying to recoup. -David
a1harps
4th Jan 2005, 03:12 pm
David,
Hope you get back to normal soon. Glad to hear from you!
-Frank
CAB
9th Feb 2005, 01:26 am
David,
Rather tricky problem fitting all the parts on a sheet!
As for the largest part, could you use area as the test?
;; Returns the parts list sorted largest first
(defun find_max_part (data / e1 e2)
(vl-sort data '(lambda (e1 e2)
(> (* (cadr e1)(caddr e1))
(* (cadr e2)(caddr e2)))))
)
(defun c:test(/ data)
(setq data (find_max_part
'(("pn3" 10.625 22.875 0)
("pn2" 12.375 24.375 1)
("pn1" 24.375 30.375 0)
))
)
data
)
David Bethel
3rd Apr 2005, 01:50 pm
Frank,
I haven't forgotten you, Just too many pots on the stove right now. Hey, I can't even see the stove. <g> -David
a1harps
3rd Apr 2005, 04:01 pm
David, I understand completely.
I am in similar condition, I cant even see the kitchen!
I can let you off the hook if you want.
I learned about some software available that only runs about $25.00.
-Frank V.
David Bethel
3rd Apr 2005, 04:11 pm
For $25 I like to see it. -David
a1harps
3rd Apr 2005, 04:14 pm
All right David, Ill get the exact name and price info to you shortly.
-Frank V.
a1harps
3rd Apr 2005, 04:24 pm
Here it is David,
WWW.Cutlistplus.com
$29.95 plus $5.95 shipping for the "light" edition.
-Frank V.
David Bethel
3rd Apr 2005, 05:30 pm
That looks interesting.
One of the reviews says:
There are a lot of panel optimizers to choose from,
I've never really searched. -David
Powered by vBulletin™ Version 4.1.2 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.