Author Topic: Material Takeoff Routine Needed.  (Read 7000 times)

0 Members and 1 Guest are viewing this topic.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10376
Re: Ok, who's pro?
« Reply #15 on: January 21, 2009, 04:45:33 PM »
After reviewing your DWG I see no help from layer to determine the parts of the window.
At this point I would propose the following:
For glass area & seals & perhaps some fasteners you could use a 'Rectangle Pick' function.
The user would pick two diagonal corners to get area and perimeter for calculating.
The the user would enter how many of this same size to calculate.
A text memo would be placed within the rectangle with the count & maybe the info and
this info would be added to an internal list.

Another routine would allow the user to select via keyword which type frame element
[heads, sills, jambs, intermediate verticals, intermediate horizontals] and the select a
line representing the element for length. Then enter the number of like elements.
Again the routine would add text to the DWG at the line selected as a memo.
Also the master list would be updated.

The user would run a routine to print or output this master list to a file.
The lisp could also tabulate fasteners etc based on the lengths & types of elements.

Would that suite your current method of takeoff operation?

We would need formulas for fasteners. i.e. fasteners per inch or per foot
Also any add needed to get the correct glass size.
I've reached the age where the happy hour is a nap. ()
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JCUTRONA

  • Guest
Re: Ok, who's pro?
« Reply #16 on: January 21, 2009, 05:13:38 PM »
All very interesting.  You must know you have made my day.  Just the "length" lsp is a great help.

The glass sizes usually follow a formula that takes the width and height of the opening (day light opening) and adds either 1 inch or 3/4 of an inch to each dimension. For example, if the opening was 20"x10" the glass would be 21"x11" for curtain wall applications.  The fasteners are usually bought in bulk any way so that is the least of my concerns.  same with anchors really.  Quantity of stock lengths of each type vertical and horizontal member and the glass unit sizes are the main objectives.

If I went back after the original drawings were done and changed all sills to a layer, all jambs to a layer and so on, could a lsp file tell me how many 24' stock lengths of each to order?  That would be amazing.  If a simple length lsp could give me the amount of 24' stock lengths and leftover "drops" that would be simply amazing.  It wouldn't even have to know which type member they were necessarily.



« Last Edit: January 21, 2009, 05:23:45 PM by JCutrona »

CAB

  • Global Moderator
  • Seagull
  • Posts: 10376
Re: Ok, who's pro?
« Reply #17 on: January 21, 2009, 05:34:17 PM »
Yes, probably so. Would need to look at the sample DWG.
I've reached the age where the happy hour is a nap. ()
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JCUTRONA

  • Guest
Re: Ok, who's pro?
« Reply #18 on: January 21, 2009, 06:03:24 PM »
ok here it is in layers.  What are my options now?

CAB

  • Global Moderator
  • Seagull
  • Posts: 10376
Re: Ok, who's pro?
« Reply #19 on: January 21, 2009, 07:25:16 PM »
That simplifies things.
I'll have some time tomorrow.
I've reached the age where the happy hour is a nap. ()
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

zoltan

  • Newt
  • Posts: 188
Re: Ok, who's pro?
« Reply #20 on: January 22, 2009, 04:21:07 PM »
If you are looking for something a bit more elaborate (and you have money to spend), there is a commercial application out there that is supposed to be prety good for this type of thing:

http://www.gmtecsoft.com/home.aspx
 

CAB

  • Global Moderator
  • Seagull
  • Posts: 10376
Re: Ok, who's pro?
« Reply #21 on: January 22, 2009, 09:34:01 PM »
Tied up most of the day and had Tennis this evening so I was Short on time.

This is what I came up with, works with example2.dwg posted above and I am relying on you to do the testing. :)
Bear in mind that this is the first draft. 8-)
Note:
I am using two layer groups: "head,jamb,sill"  and "int. horizontal,int. vertical"
The material max. length is set at 24 feet.
Code: [Select]
;;  MaterialTakeOff.lsp
;;  CAB @ TheSwamp.org
;;  Version 1.0 beta
;;
;;  From layer groups in this routine compute a cutlist based on a max length
;;  of raw material. Output the list to the command line along with the length
;;  of each drop (waste material)   Enter MatFrame to run

;;***********************************
;;   PLEASE TEST BEFORE ACTUAL USE   
;;***********************************

(defun c:matFrame (/ laylst ss MaxLen ent elst i result lay MasterList cutlst lst
                   oddlst tmp len)
  (vl-load-com)
  ;;  Layers are grouped by like material
  (setq laylst '("head,jamb,sill" "int. horizontal,int. vertical"))
  ;;  this is the stock length of the material in inches
  (setq MaxLen (* 12 24.0)) ; 24 feet
  (setq *debugmat* nil) ; turn debug mode OFF   *************

  (princ "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-")
  (princ "\nVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV")
  ;;  gather the materials from current space, only LINES matching the layers!
  (foreach lay laylst
    (if (setq ss (ssget "_X" (list (cons 8 lay) '(0 . "LINE")(cons 410 (getvar "ctab")))))
      (progn ; process the objects
        (and *debugmat* (print "SS count ")(princ (sslength ss)))
        (setq i -1
              cutlst nil)
        ;;  get the lengths only
        (while (setq ent (ssname ss (setq i (1+ i))))
          (setq elst (entget ent))
          ;; ignore < 3" as this is an end of section line
          (if (> (setq len (distance (cdr (assoc 10 elst))(cdr (assoc 11 elst)))) 3.0)
            (setq cutlst (cons len cutlst))
            (princ) ; debug
          )
        )
        (and *debugmat* (print "Raw list count ")(princ (length cutlst)))
        ;;  need to eliminate douplicate lines so only one line per section
        ;;  first sort by length
        (setq cutlst (vl-sort cutlst '<))
        (setq lst nil)
        (while (setq tmp (car cutlst)) ; eliminate douplicate
          (setq lst (cons tmp lst))
          (if (equal tmp (cadr cutlst) 0.001)
            (setq cutlst (cddr cutlst))    ; remove 2
            (setq oddlst (cons tmp oddlst) ; save odd length
                  cutlst (cdr cutlst))     ; remove 1
          )
        )
        (and *debugmat* (print "Pair remove count ")(princ (length lst)))
        (and oddlst (print "Odd lengths ")(princ oddlst))
        ;;  get the actual cutlist
        (setq MasterList (cons (list lay (setq tmp (get_cutlist lst maxlen))) MasterList))
        ;;  report to the command line the layer group & # of pieces needed
        (print lay)
        (print "Number of Lengths ")(princ (length tmp))
        (print "cutlst ")(princ tmp)
        (print "Drops")
        (mapcar '(lambda(x) (print (- MaxLen (apply '+ x)))) tmp)
               
      ) ; progn
    )
    (print)
  )
  (princ "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-")
  (textscr)
  (princ)
)
(princ "\nMaterial TakeOff loaded. Enter MatFrame to run.")
(princ)



;;  CAB 03/10/06
;;  updated 12/27/06
;;  updated 01/22/09
(defun get_cutlist (lst maxlen / cutlst itm lst ptr tl x finallst remove-at tmp tp)
  ;;  (RemoveNth 3 '(0 1 2 3 4 5))  CAB 12/27/2006
  (defun removeNth (i lst)
    (setq i (1+ i))
    (vl-remove-if '(lambda (x) (zerop (setq i (1- i)))) lst)
  )
  ;; sort the list with largest first
  (setq lst (mapcar '(lambda (x) (nth x lst)) (vl-sort-i lst '>)))
  ;;  catch any length over MaxLen & break them
  (if (not (vl-every '(lambda(x) (<= x MaxLen)) lst))
    (progn
      (while (> (setq tmp (car lst)) MaxLen)
        (setq lst (cdr(append lst (list MaxLen (- tmp MaxLen)))))
      )
      (setq lst (mapcar '(lambda (x) (nth x lst)) (vl-sort-i lst '>)))
    )
  )
  ;;  step through lst
  (while lst
    (setq cutlst (list (car lst)) ; start new cutlist w/ first item
          lst    (reverse(cdr lst)) ; remove first item
          eol    (1-(length lst)) ; point to end of list
          tl     (apply '+ cutlst) ; total length so far
          ptr    0
    )

    ;; build the cutlst
    (while
      (cond
        ((> ptr eol) nil)
        ((< (+ (nth ptr lst) tl) MaxLen)
         (setq cutlst (cons (nth ptr lst) cutlst)
               tl     (+ tl (car cutlst))
               lst    (removeNth ptr lst)
               eol    (1- eol)
         )
        )
        ((setq ptr (1+ ptr)))
      )
    )
    ;;  no more cuts fit, go to next
    (setq finallst (cons cutlst finallst)
          lst (reverse lst)
    )
  )
  (if cutlst
    (cons cutlst finallst) ; add the last odd length
    finallst
  )
)
« Last Edit: January 22, 2009, 09:38:01 PM by CAB »
I've reached the age where the happy hour is a nap. ()
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JCUTRONA

  • Guest
Re: Ok, who's pro?
« Reply #22 on: January 23, 2009, 09:53:54 AM »
Ok wow.  I was busy yesterday too but I got it copied this morning and will give it a try.
My immediate confusion however is this, why are the heads, sills, jambs grouped?  In a great deal of applications those would be different materials so I would need a seperate count for each.

Also how hard would it be to make the max length like 285 inches instead of 24 feet?  That is usually the usable length after you cut the anodizing tong marks.

Any way wow, I am gonna go try it now.  Thanks again

CAB

  • Global Moderator
  • Seagull
  • Posts: 10376
Re: Ok, who's pro?
« Reply #23 on: January 23, 2009, 09:55:03 AM »
Out for several hours. :oops:
I've reached the age where the happy hour is a nap. ()
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JCUTRONA

  • Guest
Re: Ok, who's pro?
« Reply #24 on: January 23, 2009, 11:11:33 AM »
Nice! Very nice!  I am beside myself.  This is what dreams are made of.
A couple of questions how does this work?  When I am ready to try this on a different drawing what do I need to do?  Is it a matter of naming the layers exactly as they are in "example2.dwg"?  Is that what the lisp recognizes ,the layer name? How does it compute?  And is there a way where I can run this routine separately for each frame, like select the a whole frame and then type the command. Also can we divide the groups so that the function is run separately on heads, then on jambs, then on sills, then int. verticals, then on int horizontals, ect.

ronjonp

  • Needs a day job
  • Posts: 7073
Re: Ok, who's pro?
« Reply #25 on: January 23, 2009, 11:44:56 AM »
Nice! Very nice!  I am beside myself.  This is what dreams are made of.
A couple of questions how does this work? ...

 :-D

Sorry too much caffeine...carry on.


Windows 10 x64 - AutoCAD /C3D 2020

Custom Build PC

JCUTRONA

  • Guest
Re: Ok, who's pro?
« Reply #26 on: January 23, 2009, 11:56:28 AM »

 :-D

Sorry too much caffeine...carry on.

Hey take it easy on the new guy would ya?  I'm anxious to learn?...  I'll be glad when I can laugh at in-experience?

ronjonp

  • Needs a day job
  • Posts: 7073
Re: Ok, who's pro?
« Reply #27 on: January 23, 2009, 03:36:27 PM »
Sorry...I meant no offense towards you. I was not laughing at the questions you asked, I was laughing at the "this is what dreams are made of" directly followed with "how does this work?"  :-P

Windows 10 x64 - AutoCAD /C3D 2020

Custom Build PC

JCUTRONA

  • Guest
Re: Ok, who's pro?
« Reply #28 on: January 23, 2009, 05:17:37 PM »
Yeah that probably was pretty funny huh?  And no offense taken sir. 

CAB

  • Global Moderator
  • Seagull
  • Posts: 10376
Re: Ok, who's pro?
« Reply #29 on: January 23, 2009, 05:36:37 PM »
You're quite welcome. There are may programmers here that can do this sort of thing.
As you can see LISP is a powerful tool. :)

I this this will answer most if not all the questions you posted.
The max length of material is set as follows:
(setq MaxLen (* 12 24.0)) ; 24 feet
You could replace the line with this:
(setq MaxLen 285)

The lisp uses layer names to help gather the needed information. If another drawing follows this
layer naming convention then this routine will work on them as well.

The lisp gathers LINES on the layer groups like this:
  (setq laylst '("head,jamb,sill" "int. horizontal,int. vertical"))
 
The layers may be separated like this:
  (setq laylst '("head" "jamb" "sill" "int. horizontal" "int. vertical"))
The reason I grouped them together is that I thought they were the same material.

The routine creates a selection set of LINES matching each layer group, the layer group may
containing only one layer. Then it does the following:
ignore lines < 3" as this is an end of section line
eliminate duplicate lines, IE remove one from each pair of matching length lines
report any lines that did not have a matching pair, but keeps it in the list to be calculated.

The cut list are created in an older subroutine I had & updated to use in this situation.

Then the Drops are calculated.

The report to the command line can also be directed to a text file as well.
I've reached the age where the happy hour is a nap. ()
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.