Author Topic: Adding and subtracting dimensions with lisp.  (Read 11601 times)

0 Members and 1 Guest are viewing this topic.

KOWBOI

  • Guest
Re: Adding and subtracting dimensions with lisp.
« Reply #15 on: February 26, 2010, 02:59:16 PM »
Thank you yet again. Is there a way I can add these fields together to get a total square footage and then select an attribute to place the total? I have an attribute on the title block for total square footage and previously I would use two different lisp routines. The first one would get the sqaure feet and place it on the drawing. It was not as cool as this though, I love that the field updates when the dims change. The second would let me select each individual text representing the square feet for that piece adding them up and then let me select the attribute in the title block to place the total there. That lisp does not work on fields. Thank you so much you guys are brilliant.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Adding and subtracting dimensions with lisp.
« Reply #16 on: February 26, 2010, 03:17:01 PM »
I really hope you take the time to explore the possibilities of Fields. While the provided routines are extremely helpful, they teach you nothing. Sometimes we are a little too eager to whip a little code out, not thinking of the person asking the questions and what they want/need.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

KOWBOI

  • Guest
Re: Adding and subtracting dimensions with lisp.
« Reply #17 on: February 26, 2010, 03:28:28 PM »
Actually I just recently dicovered fields and I am trying to make as much use of them as possible. I've already changed our drawing format so that certain things are updated automatically.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Adding and subtracting dimensions with lisp.
« Reply #18 on: February 26, 2010, 03:54:58 PM »
As a modification of a routine by Gile  :-)

Code: [Select]
;; ADDFIELDS (gile)
;; Insert a text field wich value is the sum of selected fields

;; Modified by Lee Mac to Accept SelSet

(defun c:AddFields (/ *error* ATT CODE ENT I LST POS RES SS)
  (vl-load-com)

  (defun *error* (msg)
    (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
        (princ (strcat "\n** Error: " msg " **")))
    (princ))
 
  (or *acdoc* (setq *acdoc* (vla-get-ActiveDocument
                              (vlax-get-acad-object))))

  (if (setq i -1 ss (ssget '((0 . "MTEXT,TEXT"))))
    (progn
     
      (while (setq ent (ssname ss (setq i (1+ i))))

        (if (and (setq code (gc:FieldCode ent))
                 (setq pos  (vl-string-search "%<" code))
                 (setq code (substr code (1+ pos)))
                 (setq pos  (vl-string-position 37 code 1 t))
                 (setq code (substr code 1 (1+ pos))))

          (if (assoc ent lst)
            (setq lst (vl-remove (assoc ent lst) lst))
            (setq lst (cons (cons ent code) lst)))))

      (if lst
        (while
          (progn
            (setq att (car (nentsel "\nSelect Attribute or Text for Field: ")))

            (cond (  (eq 'ENAME (type att))

                     (if (vl-position
                           (cdr (assoc 0 (entget att))) '("TEXT" "MTEXT" "ATTRIB"))
                       (progn

                         (setq code (cdr (last lst))

                               res (strcat "%<\\AcExpr "
                                           (lst2str (mapcar (function cdr) lst) " + ")
                                           " " (if (setq pos (vl-string-position (ascii "\\") code 1 t))
                                                 (substr code (1+ pos)) ">%")))

                         (vla-put-TextString
                           (vlax-ename->vla-object att) res)
                         
                         (vla-regen *acdoc* acActiveViewport))

                       (princ "\n** Object Must be Text, MText or Attrib **")))))))))
 
  (princ))


;;========================= ROUTINES =========================;;

;; gc:FieldCode (gile)
;; Returns the string value of a text mtext or attribute with field code
;;
;; Argument : the entity name (ENAME)

(defun gc:FieldCode (ent / foo elst xdict dict field str)

  ;;--------------------------------------------------------;;
  (defun foo (field str / pos fldID objID)
    (setq pos 0)
    (if (setq pos (vl-string-search "\\_FldIdx " str pos))
      (while (setq pos (vl-string-search "\\_FldIdx " str pos))
        (setq fldId (entget (cdr (assoc 360 field)))
              field (vl-remove (assoc 360 field) field)
              str   (strcat
                      (substr str 1 pos)
                      (if (setq objID (cdr (assoc 331 fldId)))
                        (vl-string-subst
                          (strcat "ObjId " (itoa (gc:EnameToObjectId objID)))
                          "ObjIdx"
                          (cdr (assoc 2 fldId))
                        )
                        (foo fldId (cdr (assoc 2 fldId)))
                      )
                      (substr str (1+ (vl-string-search ">%" str pos)))
                    )
        )
      )
      str
    )
  )
  ;;--------------------------------------------------------;;
 
  (setq elst (entget ent))
  (if (and
    (member (cdr (assoc 0 elst)) '("ATTRIB" "MTEXT" "TEXT"))
    (setq xdict (cdr (assoc 360 elst)))
    (setq dict (dictsearch xdict "ACAD_FIELD"))
    (setq field (dictsearch (cdr (assoc -1 dict)) "TEXT"))
      )
    (setq str (foo field (cdr (assoc 2 field))))
  )
)

;;============================================================;;

;; gc:EnameToObjectId (gile)
;; Returns the ObjectId from an ename
;;
;; Argument : an ename

(defun gc:EnameToObjectId (ename)
  ((lambda (str)
     (hex2dec
       (substr (vl-string-right-trim ">" str) (+ 3 (vl-string-search ":" str)))
     )
   )
    (vl-princ-to-string ename)
  )
)

;;============================================================;;

;; hex2dec (gile)
;; Converts an hexadecimal (string) to a decimal (int)
;;
;; Argument : a string figuring an hexadecimal

(defun hex2dec (s / r l n)
  (setq    r 0 l (vl-string->list (strcase s)))
  (while (setq n (car l))
    (setq l (cdr l)
          r (+ (* r 16) (- n (if (<= n 57) 48 55)))
    )
  )
)

;;============================================================;;

;; lst2str (gile)
;; Concatenates a list of strings and a separator into a string
;;
;; Arguments
;; lst : the list to convert
;; sep : the separator (string)

(defun lst2str (lst sep)
  (if (cdr lst)
    (strcat (car lst) sep (lst2str (cdr lst) sep))
    (car lst)
  )
)


KOWBOI

  • Guest
Re: Adding and subtracting dimensions with lisp.
« Reply #19 on: February 26, 2010, 04:45:53 PM »
WOW some more! It adds the fields then inserts the total in the attribute which is now a field and they all update automatically. This is some good stuff! One question I have though. In the dimFld.lsp how do I get it to display two decimal places only? For instance (rtos txtsum 2 2) converts the variable txtsum from a real to a string to two decimal places. I don't know how to do that with the dimFld.lsp.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Adding and subtracting dimensions with lisp.
« Reply #20 on: February 26, 2010, 04:51:36 PM »
You're welcome KOWBOI  8-)

I have added a few settings to the top of the LISP for you:

Code: [Select]
(defun c:dimFld (/ e1 e2 pt Units Prec suff)
  (vl-load-com) ;; Lee Mac  ~  26.02.10

  (setq Units 2 Prec 2 suff "sq.ft")

  (setq *doc (cond (*doc) ((vla-get-ActiveDocument
                             (vlax-get-acad-object)))))

  (or (tblsearch "LAYER" "NO_PLOT_LAYER")
      (vla-add (vla-get-layers *doc) "NO_PLOT_LAYER"))

  (if (and (setq e1 (car (entsel "\nSelect Dimension 1: ")))
           (eq "DIMENSION" (cdr (assoc 0 (entget e1))))
           (setq e2 (car (entsel "\nSelect Dimension 2: ")))
           (eq "DIMENSION" (cdr (assoc 0 (entget e2))))
           (setq pt (getpoint "\nSelect Point for Field: ")))

    (vla-put-layer
      (vla-AddMText

        (if (zerop (vla-get-ActiveSpace *doc))
          (if (eq :vlax-true (vla-get-Mspace *doc))
            (vla-get-ModelSpace *doc)
            (vla-get-PaperSpace *doc))
          (vla-get-ModelSpace *doc)) (vlax-3D-point pt) 0.

        (strcat "%<\\AcExpr "
                "%<\\AcObjProp Object(%<\\_ObjId "
                (itoa (vla-get-Objectid (vlax-ename->vla-object e1)))">%).Measurement >% * "
                "%<\\AcObjProp Object(%<\\_ObjId "
                (itoa (vla-get-Objectid (vlax-ename->vla-object e2)))">%).Measurement >%"
                " \\f \"%lu" (itoa Units) "%pr" (itoa Prec) "%ps[, " suff "]%ct8[1.07639104e-005]\" >%"))
     
    "NO_PLOT_LAYER"))

  (princ))

nivuahc

  • Guest
Re: Adding and subtracting dimensions with lisp.
« Reply #21 on: February 26, 2010, 04:53:22 PM »
I just wanted to say, Lee, that I appreciate your work on this particular issue. It filled in a few gaps for me on a small project that I'd been considering for a few days.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Adding and subtracting dimensions with lisp.
« Reply #22 on: February 26, 2010, 04:55:14 PM »
You're welcome nivuahC  8-) Happy to help mate  :-)

KOWBOI

  • Guest
Re: Adding and subtracting dimensions with lisp.
« Reply #23 on: February 26, 2010, 05:19:50 PM »
This is perfect, thank you Lee. Clearly I have have much to learn.  :ugly:

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Adding and subtracting dimensions with lisp.
« Reply #24 on: February 26, 2010, 05:21:30 PM »
No worries KOWBOI - the Field codes aren't too difficult to pick up, don't worry  ;-)