home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1993 #2 / Image.iso / cad / may93.zip / TUBE.LSP < prev   
Text File  |  1993-05-12  |  11KB  |  380 lines

  1. ;==========================================================
  2. ; TUBE.LSP  Copyright 1993 by Looking Glass Microproducts
  3. ;==========================================================
  4. ; Convert a 3D Polyline to a solid Tube 
  5. ;=============================================================
  6. (defun C:TUBE (/ ERROR PUSHVARS POPVARS SYSVARS OLD-ERROR 
  7.                NOTRANS ITEM RTOD GET_VERTS XGETDIST 
  8.                GET_RADIUS VERTS TUBE FUZZ PNAME)
  9.    (setq FUZZ 1E-6)
  10.    ;==========================================================
  11.    ; Error Handler
  12.    (defun ERROR (S)
  13.       (if (not
  14.              (member
  15.                 S
  16.                 '("Function cancelled" "console break")
  17.              )
  18.           )
  19.          (princ S)
  20.       )
  21.       (POPVARS)
  22.       (princ)
  23.    )
  24.    ;==========================================================
  25.    ; Set and Save System Variables
  26.    (defun PUSHVARS (VLIST)
  27.       (foreach PAIR VLIST
  28.          (setq
  29.             SYSVARS (cons
  30.                        (cons
  31.                           (strcase (car PAIR))
  32.                           (getvar
  33.                              (car PAIR)
  34.                           )
  35.                        )
  36.                        SYSVARS
  37.                     )
  38.          )
  39.          (if (cdr PAIR) (setvar (car PAIR) (cdr PAIR)))
  40.       )
  41.    )
  42.    ;==========================================================
  43.    ; Restore System Variables
  44.    (defun POPVARS ()
  45.       (foreach PAIR SYSVARS (setvar (car PAIR) (cdr PAIR)))
  46.       (setq
  47.          *error* OLD-ERROR
  48.       )
  49.       (setq SYSVARS nil)
  50.    )
  51.    ;==========================================================
  52.    ; Disallow transparent invocation of routine.
  53.    (defun NOTRANS ()
  54.       (cond
  55.          ((zerop (logand (getvar "cmdactive") (+ 1 2 4 8))))
  56.          ((alert
  57.              "This command may not be invoked transparently."
  58.           )
  59.          )
  60.       )
  61.    )
  62.    ;==========================================================
  63.    ; Item from association list
  64.    (defun ITEM (A B) (cdr (assoc A B)))
  65.    ;==========================================================
  66.    ; Radians to degrees
  67.    (defun RTOD (X) (/ (* 180.0 X) pi))
  68.    ;==========================================================
  69.    ; Square of a number
  70.    (defun SQR (X) (* X X))
  71.    ;==========================================================
  72.    ; Get 3d polyline
  73.    (defun GET_3DPOLY (/ AGAIN ENAME ENT)
  74.       (setq AGAIN t)
  75.       (while AGAIN
  76.          (setq
  77.             ENAME (car (entsel "\nSelect 3D polyline: "))
  78.          )
  79.          (cond
  80.             ((null ENAME) (setq AGAIN nil))
  81.             ((and
  82.                 (setq ENT (entget ENAME))
  83.                 (=
  84.                    "POLYLINE"
  85.                    (ITEM 0 ENT)
  86.                 )
  87.                 (= 8 (logand (ITEM 70 ENT) (+ 8 16 64)))
  88.              )
  89.                (setq AGAIN nil)
  90.                ENAME
  91.             )
  92.             (t
  93.                (prompt
  94.                   "Entity selected is not a 3D polyline."
  95.                )
  96.             )
  97.          )
  98.       )
  99.    )
  100.    ;==========================================================
  101.    ; Get Vertices from a 3d Polyline
  102.    (defun GET_VERTS (PNAME / ENAME ENT CLOSED VERTS P)
  103.       (setq
  104.          ENT    (entget PNAME)
  105.          CLOSED (= 1 (logand (ITEM 70 ENT) 1))
  106.          ENAME  PNAME
  107.       )
  108.       (while (progn
  109.                 (setq
  110.                    ENAME (entnext ENAME)
  111.                    ENT   (entget ENAME)
  112.                    P     (ITEM 10 ENT)
  113.                 )
  114.                 (= "VERTEX" (ITEM 0 ENT))
  115.              )
  116.          ; Ignore spline control points and
  117.          ; Duplicate points
  118.          (if (and
  119.                 (zerop (logand (ITEM 70 ENT) 16))
  120.                 (not
  121.                    (equal P (car VERTS) FUZZ)
  122.                 )
  123.              )
  124.             (setq VERTS (cons (ITEM 10 ENT) VERTS))
  125.          )
  126.       )
  127.       (if (and
  128.              CLOSED
  129.              (> (length VERTS) 2)
  130.              (not
  131.                 (equal (car VERTS) (last VERTS) FUZZ)
  132.              )
  133.           )
  134.          (setq VERTS (cons (last VERTS) VERTS))
  135.       )
  136.       (if (> (length VERTS) 1) (reverse VERTS))
  137.    )
  138.    ;=======================================================
  139.    ; Extended get distance
  140.    (defun XGETDIST (BASE PRMPT DEFAULT KWORDS)
  141.       (setq
  142.          PRMPT (if DEFAULT
  143.                   (strcat
  144.                      PRMPT
  145.                      " <"
  146.                      (rtos DEFAULT)
  147.                      ">: "
  148.                   )
  149.                   (strcat PRMPT ": ")
  150.                )
  151.       )
  152.       (initget (if DEFAULT 6 7) KWORDS)
  153.       (cond
  154.          ((if BASE (getdist BASE PRMPT) (getdist PRMPT)))
  155.          (DEFAULT
  156.          )
  157.       )
  158.    )
  159.    ;==========================================================
  160.    ; Get radius (or diameter) 
  161.    (defun GET_RADIUS (BASE PRMPT DEFAULT DIAM / RAD)
  162.       (setq
  163.          RAD (XGETDIST
  164.                 BASE
  165.                 (strcat
  166.                    (if DIAM
  167.                       "\nDiameter/<radius> "
  168.                       "\nRadius "
  169.                    )
  170.                    PRMPT
  171.                 )
  172.                 DEFAULT
  173.                 (if DIAM "Diameter" "")
  174.              )
  175.       )
  176.       (if (= RAD "Diameter")
  177.          (setq
  178.             RAD (*
  179.                    0.5
  180.                    (XGETDIST
  181.                       BASE
  182.                       (strcat "\nDiameter " PRMPT)
  183.                       (if DEFAULT
  184.                          (* 2.0 DEFAULT)
  185.                       )
  186.                       ""
  187.                    )
  188.                 )
  189.          )
  190.       )
  191.       RAD
  192.    )
  193.    ;==========================================================
  194.    ; Get tube radius and elbow radius
  195.    (defun GET_RADII ()
  196.       (if (not (numberp TUBE_RADIUS)) (setq TUBE_RADIUS nil))
  197.       (if (not (numberp ELBOW_RADIUS))
  198.          (setq ELBOW_RADIUS nil)
  199.       )
  200.       (setq
  201.          TUBE_RADIUS (GET_RADIUS
  202.                         (car VERTS)
  203.                         "of tube"
  204.                         TUBE_RADIUS
  205.                         t
  206.                      )
  207.       )
  208.       (if (>= TUBE_RADIUS ELBOW_RADIUS)
  209.          (setq ELBOW_RADIUS nil)
  210.       )
  211.       (while (>=
  212.                 TUBE_RADIUS
  213.                 (setq
  214.                    ELBOW_RADIUS (GET_RADIUS
  215.                                    (car VERTS)
  216.                                    "of elbow"
  217.                                    ELBOW_RADIUS
  218.                                    nil
  219.                                 )
  220.                 )
  221.              )
  222.          (prompt
  223.             "\nElbow radius must be greater than tube radius."
  224.          )
  225.          (setq ELBOW_RADIUS nil)
  226.       )
  227.    )
  228.    ;==========================================================
  229.    ; Make the tube
  230.    (defun MAKE_TUBE (VERTS / P1 P2 P3 PA PB PC PD PE A1 A2 D1 
  231.                      D2 CLOSED SS SKIP_FIRST)
  232.       (setq CLOSED (equal (car VERTS) (last VERTS) FUZZ))
  233.       (if CLOSED
  234.          (setq
  235.             VERTS (append
  236.                      (list (cadr (reverse VERTS)))
  237.                      VERTS
  238.                      (list (cadr VERTS))
  239.                   )
  240.          )
  241.       )
  242.       (setq
  243.          SKIP_FIRST CLOSED
  244.          SS         (ssadd)
  245.          P1         (car VERTS)
  246.          P2         (cadr VERTS)
  247.          P3         (caddr VERTS)
  248.          VERTS      (cdddr VERTS)
  249.       )
  250.       (while P2
  251.          (cond
  252.             ((and P3 (inters P1 P2 P2 P3 t))
  253.                (command
  254.                   "_ucs" "3p" P2 P1 P3
  255.                )
  256.                (setq
  257.                   A1 (angle '(0 0 0) (trans P3 0 1))
  258.                   A2 (* 0.5 A1)
  259.                   D2 (/ ELBOW_RADIUS (sin A2))
  260.                   D1 (sqrt (- (SQR D2) (SQR ELBOW_RADIUS)))
  261.                   PA (trans
  262.                         (setq PD (polar '(0 0 0) 0 D1))
  263.                         1
  264.                         0
  265.                      )
  266.                   PB (trans (polar '(0 0 0) A1 D1) 1 0)
  267.                   PC (trans
  268.                         (setq PE (polar '(0 0 0) A2 D2))
  269.                         1
  270.                         0
  271.                      )
  272.                )
  273.                (if SKIP_FIRST
  274.                   ; If closed, don't draw the section
  275.                   (progn
  276.                      (setq SKIP_FIRST nil)
  277.                      (command "_ucs" "p")
  278.                   )
  279.                   (progn
  280.                      (command "_ucs" "3p" PD PE "@0,0,1")
  281.                      (ssadd
  282.                         (solcyl
  283.                            (trans P1 0 1)
  284.                            TUBE_RADIUS
  285.                            "c"
  286.                            (trans PA 0 1)
  287.                         )
  288.                         SS
  289.                      )
  290.                      (command "_circle" '(0 0 0) TUBE_RADIUS)
  291.                      (ssadd
  292.                         (solrev
  293.                            (entlast)
  294.                            (list ELBOW_RADIUS 0 0)
  295.                            (list
  296.                               ELBOW_RADIUS
  297.                               -1
  298.                               0
  299.                            )
  300.                            (- 180.0 (RTOD A1))
  301.                         )
  302.                         SS
  303.                      )
  304.                      (command "_ucs" "p")
  305.                      (command "_ucs" "p")
  306.                   )
  307.                )
  308.                (setq
  309.                   P1    PB
  310.                   P2    P3
  311.                   P3    (car VERTS)
  312.                   VERTS (cdr VERTS)
  313.                )
  314.             )
  315.             (P3
  316.                (setq P2 P3 P3 (car VERTS) VERTS (cdr VERTS))
  317.             )
  318.             (t
  319.                (if (not CLOSED)
  320.                   (ssadd
  321.                      (SOLCYL P1 TUBE_RADIUS "c" P2)
  322.                      SS
  323.                   )
  324.                )
  325.                (setq P2 nil)
  326.             )
  327.          )
  328.       )
  329.       (solunion SS)
  330.       (setq SS nil)
  331.    )
  332.    ;==========================================================
  333.    ; Main Routine
  334.    (defun TUBE ()
  335.       (cond
  336.          ((not (member (findfile "ame.exp") (ads)))
  337.             (alert
  338.                "\nAME must be xloaded to run this command."
  339.             )
  340.          )
  341.          ((not (setq PNAME (GET_3DPOLY))))
  342.          ((not (setq VERTS (GET_VERTS PNAME)))
  343.             (alert
  344.                "Zero length 3D polyline"
  345.             )
  346.          )
  347.          (t
  348.             (PUSHVARS
  349.                '(("blipmode" . 0)
  350.                   ("ucsicon" . 0)
  351.                   ("gridmode" . 0)
  352.                )
  353.             )
  354.             (command "_ucs" "w")
  355.             (GET_RADII)
  356.             (MAKE_TUBE VERTS)
  357.             (command "_ucs" "p")
  358.          )
  359.       )
  360.    )
  361.    ;==========================================================
  362.    ; Body of c:tube  
  363.    (if (NOTRANS)
  364.       (progn
  365.          (setq OLD-ERROR *error* *error* ERROR)
  366.          (setvar "cmdecho" 0)
  367.          (command "_undo" "mark")
  368.          (PUSHVARS '(("osmode" . 0)))
  369.          (TUBE)
  370.          (POPVARS)
  371.       )
  372.    )
  373.    (princ)
  374. )
  375. (princ
  376.    "  TUBE.LSP (Copyright 1993 by Looking Glass Microproducts) loaded."
  377. )
  378. (princ)
  379. 
  380.