home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / autocad / makelt.arj / MAKELT.LSP
Lisp/Scheme  |  1991-06-03  |  15KB  |  935 lines

  1. ;;;   MAKELT.lsp
  2.  
  3. ;;;   Copyright (C) 1991 by Autodesk, Inc.
  4.  
  5. ;;;  
  6.  
  7. ;;;   Permission to use, copy, modify, and distribute this software and its
  8.  
  9. ;;;   documentation for any purpose and without fee is hereby granted.  
  10.  
  11. ;;;
  12.  
  13. ;;;   THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. 
  14.  
  15. ;;;   ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF 
  16.  
  17. ;;;   MERCHANTABILITY ARE HEREBY DISCLAIMED.
  18.  
  19. ;;; 
  20.  
  21. ;;;   by Carl B. Bethea
  22.  
  23. ;;;   29 April 1991
  24.  
  25. ;;; 
  26.  
  27. ;;;--------------------------------------------------------------------------;
  28.  
  29. ;;;   DESCRIPTION
  30.  
  31. ;;;
  32.  
  33. ;;;
  34.  
  35. ;;;   MakeLT creates and edits linetypes. The function has four options:
  36.  
  37. ;;;
  38.  
  39. ;;;   Pattern - This option creates lines and points representing the linetype 
  40.  
  41. ;;;   definition at an LTSCALE of 1.0. You can then edit this pattern adding 
  42.  
  43. ;;;   to it or subtracting from it or changing the components, and then use 
  44.  
  45. ;;;   the New option, below, to create a new linetype definition or redefine 
  46.  
  47. ;;;   the existing linetype.
  48.  
  49. ;;;
  50.  
  51. ;;;   LTscale - Like Pattern, this option draws lines and points representing 
  52.  
  53. ;;;   the linetype definition, but allows you to use an LTSCALE other than 
  54.  
  55. ;;;   1.0. This option is useful for creating variations of existing linetypes 
  56.  
  57. ;;;   that will then be used at different scales within the drawing.
  58.  
  59. ;;;
  60.  
  61. ;;;   Match - This option is similar to the LTscale option, in as much as it 
  62.  
  63. ;;;   uses the current LTSCALE setting to create a new linetype definition. 
  64.  
  65. ;;;   The difference is that it does not draw the pattern; instead it writes 
  66.  
  67. ;;;   the definiton directly to file.
  68.  
  69. ;;;
  70.  
  71. ;;;   New - This option allows you to select lines and points which represent 
  72.  
  73. ;;;   a linetype pattern. The function then calculates the linetype definition 
  74.  
  75. ;;;   data, writes that data to the LIN file and then loads the linetype into 
  76.  
  77. ;;;   memory. The routine assumes that you have selected a full linetype 
  78.  
  79. ;;;   pattern, that is, that the last segment is roughly equal to the first. 
  80.  
  81. ;;;   If you look at the definition in the LIN file, you will see that the 
  82.  
  83. ;;;   last segment is assumed to be a repeat of the first; so, MakeLT makes 
  84.  
  85. ;;;   the same assumtion and automatically throws out the last segment before 
  86.  
  87. ;;;   writing the data to file. It's important to select the last segment, 
  88.  
  89. ;;;   however, because MakeLT uses it to calculate the pen-up movement for the 
  90.  
  91. ;;;   final gap in the pattern.
  92.  
  93. ;;;
  94.  
  95. ;;;   As a side note, one of the more interesting subroutines in this program 
  96.  
  97. ;;;   is SYSVAR. It is used to set and reset system variables during the 
  98.  
  99. ;;;   running of the program. Instead of using a global variable to store the 
  100.  
  101. ;;;   old variables settings, the program employs a unique attribute of the 
  102.  
  103. ;;;   LISP programming language. The function redefines itself while it is 
  104.  
  105. ;;;   running, and in this way stores the old settings for the system 
  106.  
  107. ;;;   variables internally. 
  108.  
  109. ;;;
  110.  
  111. ;;;
  112.  
  113. ;;;-- mk_getlt ---------------------------------------------
  114.  
  115. ;;;   find the linetype of an entity
  116.  
  117. ;;;   get the defintion
  118.  
  119. ;;;   spawns: <lname tpl>
  120.  
  121. ;;;
  122.  
  123. (defun mk_getlt (ent / dxf data)
  124.  
  125.  
  126.  
  127.    (defun dxf (x)(cdr(assoc x data)))
  128.  
  129.  
  130.  
  131.    (setq data (entget ent)
  132.  
  133.         lname (if (dxf 6) 
  134.  
  135.                   (dxf 6)
  136.  
  137.                   (progn
  138.  
  139.                      (setq data (tblsearch "LAYER" (dxf 8)))
  140.  
  141.                      (dxf 6) 
  142.  
  143.                   )
  144.  
  145.               )
  146.  
  147.          data (tblsearch "LTYPE" lname)
  148.  
  149.           tpl (dxf 40); total pattern length
  150.  
  151.    )
  152.  
  153.    (mapcar '(lambda (i)
  154.  
  155.               (cdr i)
  156.  
  157.             )
  158.  
  159.             (member (assoc 49 data) data)
  160.  
  161.    )
  162.  
  163. )
  164.  
  165. ;;;   
  166.  
  167. ;;;
  168.  
  169. ;;;-- mk_drawlt --------------------------------------------
  170.  
  171. ;;;   draw lines and points to represent the linetype
  172.  
  173. ;;;   (idea: use plines for width)
  174.  
  175. ;;;
  176.  
  177. (defun mk_drawlt (lts / p1 ent vector i)
  178.  
  179.    (if (setq ent (entsel "\nPick a example of the linetype: "))
  180.  
  181.       (progn
  182.  
  183.          (sysvar "cmdecho" 0)
  184.  
  185.          (setq ent (car ent)
  186.  
  187.             vector (mk_getlt ent)
  188.  
  189.          )
  190.  
  191.          (if lts        
  192.  
  193.             (setq vector 
  194.  
  195.                (mapcar '(lambda (i)
  196.  
  197.                            (* i lts)
  198.  
  199.                         )
  200.  
  201.                         vector
  202.  
  203.                )
  204.  
  205.             )
  206.  
  207.          )
  208.  
  209.          (setq vector (append vector (list (car vector))))
  210.  
  211.  
  212.  
  213.          (setq celt (getvar "CELTYPE")
  214.  
  215.                  p1 (getpoint "\nStart point for pattern: ")
  216.  
  217.          )
  218.  
  219.          (command "linetype" "Set" "Continuous" "")               
  220.  
  221.          (foreach i vector
  222.  
  223.             (cond 
  224.  
  225.                ((minusp i)
  226.  
  227.                   (setq p1 (polar p1 0 (abs i)))
  228.  
  229.                )
  230.  
  231.                ((= 0.0 i)
  232.  
  233.                   (command "point" p1)
  234.  
  235.                )
  236.  
  237.                (T (command "line" 
  238.  
  239.                      p1 
  240.  
  241.                      (setq p1 (polar p1 0 i))
  242.  
  243.                      ""
  244.  
  245.                   )
  246.  
  247.                )
  248.  
  249.            );cond
  250.  
  251.          );foreach
  252.  
  253.          (command "linetype" "Set" CELT "")               
  254.  
  255.          (sysvar "cmdecho" nil)
  256.  
  257.       );progn
  258.  
  259.       (prompt " none found.")         
  260.  
  261.    );if
  262.  
  263. )
  264.  
  265. ;;;
  266.  
  267. ;;;
  268.  
  269. ;;;-- mk_sslist --------------------------------------------
  270.  
  271. ;;;   convert selection-set <SS> 
  272.  
  273. ;;;   into a list of entities 
  274.  
  275. ;;;
  276.  
  277. (defun mk_sslist (ss / n p)
  278.  
  279.    (repeat (setq n (sslength ss))      ;seed n
  280.  
  281.       (setq n (1- n)                   ;index number
  282.  
  283.             p (cons (ssname ss n) p)
  284.  
  285.       )  
  286.  
  287.    )
  288.  
  289. ); mk_sslist
  290.  
  291. ;;;
  292.  
  293. ;;;
  294.  
  295. ;;;-- mk_clean ---------------------------------------------
  296.  
  297. ;;;   sort the vector list
  298.  
  299. ;;;
  300.  
  301. (defun mk_clean (alist / n i clist)
  302.  
  303.    (repeat (setq n (length alist))
  304.  
  305.       (setq i (car  alist))
  306.  
  307.       (foreach c alist
  308.  
  309.          (if (> (caar c) (caar i)) (setq i c)) 
  310.  
  311.       )
  312.  
  313.       (setq clist (cons i clist)
  314.  
  315.             alist (append (cdr (member i (reverse alist))); remove i
  316.  
  317.                           (cdr (member i alist))          ; from list
  318.  
  319.                   )
  320.  
  321.       );setq
  322.  
  323.    )
  324.  
  325.    clist
  326.  
  327. );mk_clean
  328.  
  329. ;;;
  330.  
  331. ;;;
  332.  
  333. ;;;-- mk_getparts ------------------------------------------
  334.  
  335. ;;;   collect the entities of the line defintion 
  336.  
  337. ;;;   sort them by start point
  338.  
  339. ;;;
  340.  
  341. (defun mk_getparts (/ dxf data parts vector)
  342.  
  343.  
  344.  
  345.    (defun dxf (x)(cdr(assoc x data)))
  346.  
  347.    
  348.  
  349.    (prompt "\nSelect lines and points defining a linetype: ")
  350.  
  351.    (cond 
  352.  
  353.       ((setq parts (ssget))
  354.  
  355.          (setq parts (mk_sslist parts)
  356.  
  357.               vector (mapcar 
  358.  
  359.                        '(lambda (i)
  360.  
  361.                            (setq data (entget i))
  362.  
  363.                            (cons 
  364.  
  365.                               (dxf 10) 
  366.  
  367.                               (if (dxf 11)
  368.  
  369.                                   (distance (dxf 10)(dxf 11))
  370.  
  371.                                   0
  372.  
  373.                               )
  374.  
  375.                            )
  376.  
  377.                         )
  378.  
  379.                         parts
  380.  
  381.                      );mapcar
  382.  
  383.               vector (mk_clean vector)
  384.  
  385.          );setq
  386.  
  387.       )
  388.  
  389.       (T nil)
  390.  
  391.   )
  392.  
  393. )
  394.  
  395. ;;;
  396.  
  397. ;;;
  398.  
  399. ;;;-- mk_calpen --------------------------------------------
  400.  
  401. ;;;   calculate the pen movements
  402.  
  403. ;;;   return "pen-down,pen-up" codes
  404.  
  405. ;;;
  406.  
  407. (defun mk_calpen (v1 v2 / down up)
  408.  
  409.    (setq 
  410.  
  411.         up (distance 
  412.  
  413.               (polar (car v1) 0 (cdr v1))
  414.  
  415.               (car v2)
  416.  
  417.            )
  418.  
  419.       down (if (= 0 (cdr v1)) 
  420.  
  421.               "0"
  422.  
  423.                (rtos (cdr v1) 2 2)
  424.  
  425.            )
  426.  
  427.    )
  428.  
  429.    (strcat
  430.  
  431.       down 
  432.  
  433.       ",-" 
  434.  
  435.       (rtos up 2 2)
  436.  
  437.       ","
  438.  
  439.    )
  440.  
  441. )           
  442.  
  443. ;;;
  444.  
  445. ;;;
  446.  
  447. ;;;-- mk_deflin --------------------------------------------
  448.  
  449. ;;;   define the linetype 
  450.  
  451. ;;;   requires <vector> set by mk_getparts
  452.  
  453. ;;;
  454.  
  455. (defun mk_deflin (/ i )
  456.  
  457.    (setq i
  458.  
  459.       (apply 'strcat
  460.  
  461.          (mapcar 'mk_calpen
  462.  
  463.             (reverse (cdr (reverse vector))); everything but the last
  464.  
  465.             (cdr vector)                    ; everything but the first
  466.  
  467.          )
  468.  
  469.       )   
  470.  
  471.    )
  472.  
  473.    (substr i 1 (1- (strlen i)))             ; take off last comma 
  474.  
  475. )
  476.  
  477. ;;;
  478.  
  479. ;;;
  480.  
  481. ;;;-- sysvar -----------------------------------------------
  482.  
  483. ;;;   change system variable, save old value, reset later
  484.  
  485. ;;;   (sysvar <system variable> <new value>)
  486.  
  487. ;;;   (sysvar "cmdecho" 1) sets a single system variable
  488.  
  489. ;;;   (sysvar '("cmdecho" "blipmode") '(1 0)) multiple variables
  490.  
  491. ;;;   (sysvar <system variable> nil) resets specified variables(s)
  492.  
  493. ;;;   (sysvar nil nil) resets all system variables              
  494.  
  495. ;;;
  496.  
  497. (defun sysvar (what new / sys_var sys_set old sys_unset sys_cond)
  498.  
  499.  
  500.  
  501.    (setq sys_var nil)
  502.  
  503.  
  504.  
  505.    ;; make dotted pair, add it to the front of list.
  506.  
  507.    (defun sys_set (what new)         
  508.  
  509.       (setq what (strcase what t))
  510.  
  511.  
  512.  
  513.       ;; make sure the same pair is not extant, 
  514.  
  515.       ;; otherwise sys_unset will screw-up the list.
  516.  
  517.       ;; FILO accounting will reset previous change
  518.  
  519.       (if (not 
  520.  
  521.              (member 
  522.  
  523.                 (cons what (setq old (getvar what))) 
  524.  
  525.                 sys_var
  526.  
  527.              )
  528.  
  529.           )
  530.  
  531.           (setq  sys_var 
  532.  
  533.              (cons 
  534.  
  535.                  (cons what old)
  536.  
  537.                  sys_var
  538.  
  539.              )
  540.  
  541.           )         
  542.  
  543.       )
  544.  
  545.       (setvar what new)
  546.  
  547.    )
  548.  
  549.  
  550.  
  551.    ;; change setvar to old setting,
  552.  
  553.    ;; remove the pair from the list
  554.  
  555.    (defun sys_unset (what) 
  556.  
  557.       (setq what (strcase what t))
  558.  
  559.       (setvar what 
  560.  
  561.          (cdr (setq old (assoc what sys_var)))
  562.  
  563.       )
  564.  
  565.       (setq sys_var 
  566.  
  567.          (append 
  568.  
  569.             (cdr (member old (reverse sys_var))); remove old
  570.  
  571.             (cdr (member old sys_var))          ; from list
  572.  
  573.          )
  574.  
  575.       )
  576.  
  577.    )
  578.  
  579.  
  580.  
  581.    (defun sys_cond (what new)
  582.  
  583.    (cond
  584.  
  585.  
  586.  
  587.       ;; if both variables are set
  588.  
  589.       ;; then set the system variables
  590.  
  591.       ;; if <what> is not a single string
  592.  
  593.       ;; then assume it is a list and that
  594.  
  595.       ;; make sure they are the same length
  596.  
  597.       ((and what new)
  598.  
  599.          (if (eq 'STR (type what))
  600.  
  601.              (sys_set what new)
  602.  
  603.              (if (= (length what)(length new))
  604.  
  605.                  (mapcar 'sys_set what new)
  606.  
  607.                  (prompt "SYSVAR: argument mismatch.\n")
  608.  
  609.              )
  610.  
  611.          )
  612.  
  613.       )
  614.  
  615.       
  616.  
  617.       ;; <new> is not set, but <what> is
  618.  
  619.       ;; undo the setvar
  620.  
  621.       ;; if list is not a single string
  622.  
  623.       ;; assume that it is a list, do all
  624.  
  625.       ((eq 'STR (type what))
  626.  
  627.          (sys_unset what)
  628.  
  629.       )
  630.  
  631.       (what
  632.  
  633.          (mapcar 'sys_unset what)
  634.  
  635.       )
  636.  
  637.  
  638.  
  639.       ;; both arguments are nil
  640.  
  641.       ;; reset all setvars
  642.  
  643.       (T 
  644.  
  645.          (foreach old sys_var
  646.  
  647.             (setvar (car old)(cdr old))
  648.  
  649.          )
  650.  
  651.          (setq sys_var nil)   
  652.  
  653.       )
  654.  
  655.    );cond
  656.  
  657.    )
  658.  
  659.    
  660.  
  661.    ;; execute the internal function 
  662.  
  663.    (sys_cond what new)
  664.  
  665.    
  666.  
  667.    ;; redefine sysvar to contain the new value 
  668.  
  669.    ;; of the local variable sys_var
  670.  
  671.    (setq 
  672.  
  673.       sysvar (cons (car sysvar)
  674.  
  675.                (cons    
  676.  
  677.                    (list 'setq 'sys_var (list 'quote  sys_var))
  678.  
  679.                    (cddr sysvar)
  680.  
  681.                )
  682.  
  683.              )
  684.  
  685.    )
  686.  
  687.    sys_var
  688.  
  689. )
  690.  
  691. ;;;
  692.  
  693. ;;;
  694.  
  695. ;;;-- mk_err -----------------------------------------------
  696.  
  697. ;;; internal error handler
  698.  
  699. ;;;
  700.  
  701. (defun mk_err (msg)
  702.  
  703.    (if (/= msg "Function cancelled")
  704.  
  705.       (princ (strcat "\nError: " s))
  706.  
  707.       (princ msg)
  708.  
  709.    )
  710.  
  711.    (command "linetype" "Set" CELT "")               
  712.  
  713.    (sysvar nil nil)
  714.  
  715.    (setq *error* olderr olderr nil) 
  716.  
  717.    (princ)
  718.  
  719. )
  720.  
  721. ;;;
  722.  
  723. ;;;
  724.  
  725. ;;;-- c:makelt ---------------------------------------------
  726.  
  727. ;;; make a linetype definiton from a drawing 
  728.  
  729. ;;;
  730.  
  731. (defun c:makelt (/ fname lname tpl lts line 
  732.  
  733.                    code vector celt)
  734.  
  735.  
  736.  
  737.    (setq olderr *error*
  738.  
  739.          *error* mk_err
  740.  
  741.    )
  742.  
  743.  
  744.  
  745.    ;; expert=3 automatically overwrites existing linetype
  746.  
  747.    (sysvar '("blipmode" "cmdecho" "expert") 
  748.  
  749.            '(   0           1         3   )
  750.  
  751.    )
  752.  
  753.  
  754.  
  755.    (initget "New Pattern LTscale Match")
  756.  
  757.    (if (null 
  758.  
  759.           (setq code 
  760.  
  761.              (getkword 
  762.  
  763.    "\nLinetype editor: draw Pattern/draw LTscale/Match ltscale/<New>: "
  764.  
  765.              )
  766.  
  767.           )
  768.  
  769.        )
  770.  
  771.        (setq code "New")
  772.  
  773.    )
  774.  
  775.    
  776.  
  777.    (cond
  778.  
  779.       ((and (= code "New")
  780.  
  781.             (< 1 (length (setq vector (mk_getparts))) 8)
  782.  
  783.        )
  784.  
  785.          (setq line (mk_deflin)
  786.  
  787.               lname (getstring "\nLinetype name: ")
  788.  
  789.          )
  790.  
  791.          (command "linetype" "create" 
  792.  
  793.             lname
  794.  
  795.             pause ; file
  796.  
  797.             "MakeLT" ; description
  798.  
  799.             line  ; write the data
  800.  
  801.             "load" lname "" ""
  802.  
  803.          )
  804.  
  805.       );New
  806.  
  807.       ((= code "New")
  808.  
  809.          (prompt "Error: must have between 2 and 12 dash/dots.")
  810.  
  811.       )
  812.  
  813.       ((= code "Pattern")
  814.  
  815.          (mk_drawlt nil)
  816.  
  817.       )
  818.  
  819.       ((= code "LTscale")
  820.  
  821.          (if (null 
  822.  
  823.                 (setq lts 
  824.  
  825.                    (getdist 
  826.  
  827.                       (strcat "\nNew LTscale <" 
  828.  
  829.                          (rtos (getvar "ltscale")) 
  830.  
  831.                          ">: "
  832.  
  833.                       )
  834.  
  835.                    )
  836.  
  837.                 )
  838.  
  839.              )
  840.  
  841.              (setq lts (getvar "ltscale"))
  842.  
  843.          )
  844.  
  845.          (mk_drawlt lts)
  846.  
  847.       ) 
  848.  
  849.       ((and (= code "Match") 
  850.  
  851.             (setq vector (entsel "\nPick a line to match: "))
  852.  
  853.        )
  854.  
  855.          (setq lts (getvar "ltscale")
  856.  
  857.             vector (mk_getlt (car vector))
  858.  
  859.             vector (mapcar '(lambda (i)
  860.  
  861.                                (strcat
  862.  
  863.                                   (rtos (* i lts) 2 2)
  864.  
  865.                                   ","
  866.  
  867.                                )
  868.  
  869.                             )
  870.  
  871.                             vector
  872.  
  873.                    )
  874.  
  875.             vector (apply 'strcat vector)       
  876.  
  877.               line (substr vector 1 (1- (strlen vector)))               
  878.  
  879.               lname (getstring 
  880.  
  881.                        (strcat "\nNew name for " lname ": ")
  882.  
  883.                     )
  884.  
  885.          )
  886.  
  887.          (if (and line (/= "" lname))
  888.  
  889.             (command "linetype" "create" 
  890.  
  891.                lname
  892.  
  893.                pause ; file
  894.  
  895.                "MakeLT" ; description
  896.  
  897.                line  ; vector defintion
  898.  
  899.                "load" lname "" ""
  900.  
  901.             )
  902.  
  903.             (prompt " invalid input.")
  904.  
  905.          )
  906.  
  907.       )
  908.  
  909.       (T (prompt " invalid input."))   
  910.  
  911.    )   
  912.  
  913.    (sysvar nil nil)
  914.  
  915.    (setq *error* olderr olderr nil)
  916.  
  917.    (princ)
  918.  
  919. )
  920.  
  921. ;;;   
  922.  
  923. ;;;-- end of file ------------------------------------------
  924.  
  925. (prompt "\nMakeLT options: ")
  926.  
  927. (prompt "\nPattern - draw the linetype pattern of a selected line.")
  928.  
  929. (prompt "\nLTscale - draw the pattern at a specified linetype scale.")
  930.  
  931. (prompt "\n  Match - create a definiton to match a pattern and scale.")
  932.  
  933. (prompt "\n    New - select objects which define a new linetype pattern.")
  934.  
  935. (princ)