Author Topic: [XDrX-PlugIn(41)] Feel free to do whatever you want" -- Free Rectang  (Read 805 times)

0 Members and 1 Guest are viewing this topic.

xdcad

  • Bull Frog
  • Posts: 479
Draw a rectangle freely and customize the drag step size

Code - Auto/Visual Lisp: [Select]
  1. (defun c:XDTB_RectFree (/       baseline-x      baseline-y      basept
  2.                         distx   disty   dynpt   e1      e2      el
  3.                         ents    ents-bak        h       info    info1
  4.                         m_rec_ent       n       num     p_1     p_2
  5.                         p1      p2      pmid    pt2     pt3     ra
  6.                         ret1    ss      tbox    tf      tmp     txt1
  7.                         txt2    txtp    v       val     x       xdir
  8.                         ydir    _callback       roundto
  9.                        )
  10.   (defun _prompt1 ()
  11.     (xdrx_prompt
  12.       "\nCurrent setting: Line Width("
  13.       #xd_var_global_lw_width
  14.       ") Color("
  15.       #xd_var_global_ent_color
  16.       ") Step("
  17.       (xdrx-getvar "distancesnap")
  18.       ")\n"
  19.     )
  20.   )
  21.   (defun _callback (dynpt)
  22.     (if (not (equal dynpt basept 1e-3))
  23.       (progn
  24.         (setq baseline-x (list basept (mapcar '+ basept xdir))
  25.               baseline-y (list basept (mapcar '+ basept ydir))
  26.               disty      (- (xdrx-point-dist2line
  27.                               dynpt
  28.                               (car baseline-x)
  29.                               (cadr baseline-x)
  30.                             )
  31.                          )
  32.         )
  33.         (setq roundto (xdrx-getvar "distancesnap"))
  34.         (setq
  35.           disty (xdrx-math-roundto disty roundto)
  36.           distx (xdrx-point-dist2line
  37.                   dynpt
  38.                   (car baseline-y)
  39.                   (cadr baseline-y)
  40.                 )
  41.           distx (xdrx-math-roundto distx roundto)
  42.         )
  43.         (if (equal distx 0.0 1e-3)
  44.           (setq distx (xdrx-getvar "distancesnap"))
  45.         )
  46.         (if (equal disty 0.0 1e-3)
  47.           (setq disty (xdrx-getvar "distancesnap"))
  48.         )
  49.         (setq
  50.           dynpt (mapcar
  51.                   '+
  52.                   (mapcar '+ basept (xdrx-vector-product xdir distx))
  53.                   (xdrx-vector-product ydir disty)
  54.                 )
  55.         )
  56.         (setq ret1 dynpt)
  57.         (XD::Drag:CallBackSetDynPnt dynpt)
  58.         (setq h (xd::doc:getpickboxheight))
  59.         (setq pt2 (mapcar '+ basept (xdrx-vector-product xdir distx))
  60.               pt3 dynpt
  61.         )
  62.         (xdrx-setpropertyvalue
  63.           txt1
  64.           "textstring"
  65.           (rtos (abs distx) 2 1)
  66.           "position"
  67.           (setq txtp (xdrx-line-midp basept pt2))
  68.           "textheight"
  69.           h
  70.         )
  71.         (setq tbox (xdrx-getpropertyvalue txt1 "textbox")
  72.               tbox (xd::pnts:close tbox)
  73.               tbox (xdrx-points-offset (/ h 3.0) tbox)
  74.               pmid (xd::geom:get9pt tbox 2)
  75.               v    (xdrx-vector-normalize (mapcar '- (cadr tbox) (car tbox)))
  76.         )
  77.         (xdrx-entity-align
  78.           txt1
  79.           (if (xdrx-vector-iscodirectional v xdir (/ pi 4))
  80.             pmid
  81.             (xd::geom:get9pt tbox 4)
  82.           )
  83.           v
  84.           (mapcar '+
  85.                   (xdrx-line-midp basept pt2)
  86.                   (xdrx-vector-product
  87.                     (xdrx-vector-normalize (mapcar '- pt2 basept))
  88.                     (/ h 3.0)
  89.                   )
  90.           )
  91.           (if (xdrx-vector-iscodirectional v xdir (/ pi 4))
  92.             xdir
  93.             ydir
  94.           )
  95.         )
  96.         (xd::text:adjust txt1)
  97.         (setq tbox (xdrx-getpropertyvalue txt1 "textbox")
  98.               tbox (xd::pnts:close tbox)
  99.               tbox (xdrx-points-offset (/ h 3.0) tbox)
  100.               tbox (xd::pnts:close tbox)
  101.         )
  102.         (xdrx-grdraw 8 -1 tbox)
  103.         (xdrx-grdraw 2 1 txt1)
  104.         (xdrx-setpropertyvalue
  105.           txt2
  106.           "textstring"
  107.           (rtos (abs disty) 2 1)
  108.           "position"
  109.           (setq txtp (xdrx-line-midp pt2 pt3))
  110.           "textheight"
  111.           h
  112.         )
  113.         (setq tbox (xdrx-getpropertyvalue txt2 "textbox")
  114.               tbox (xd::pnts:close tbox)
  115.               tbox (xdrx-points-offset (/ h 3.0) tbox)
  116.               pmid (xd::geom:get9pt tbox 4)
  117.               v    (xdrx-vector-normalize (mapcar '- (cadr tbox) (car tbox)))
  118.         )
  119.         (xdrx-entity-align
  120.           txt2
  121.           (if (xdrx-vector-iscodirectional v xdir (/ pi 4))
  122.             pmid
  123.             (xd::geom:get9pt tbox 4)
  124.           )
  125.           v
  126.           (mapcar '+
  127.                   (xdrx-line-midp pt2 pt3)
  128.                   (xdrx-vector-product
  129.                     (xdrx-vector-normalize (mapcar '- pt3 pt2))
  130.                     (/ h 3.0)
  131.                   )
  132.           )
  133.           (if (xdrx-vector-iscodirectional v xdir (/ pi 4))
  134.             xdir
  135.             ydir
  136.           )
  137.         )
  138.         (xd::text:adjust txt2)
  139.         (setq tbox (xdrx-getpropertyvalue txt2 "textbox")
  140.               tbox (xd::pnts:close tbox)
  141.               tbox (xdrx-points-offset (/ h 3.0) tbox)
  142.               tbox (xd::pnts:close tbox)
  143.         )
  144.         (xdrx-grdraw 8 -1 tbox)
  145.         (xdrx-grdraw 2 1 txt2)
  146.       )
  147.     )
  148.   )
  149.   (defun _process (e1 e2)
  150.     (setq ra (xd::curve:relation e1 e2))
  151.     (cond ((or (= ra 0) (= ra 4)))
  152.           ((or (= ra 2) (= ra 3)) (setq tmp (xdrx_get_union e1 e2)))
  153.           ((or (= ra 1) (= ra 5))
  154.            (setq tmp (xdrx_get_subtract e2 e1))
  155.           )
  156.     )
  157.     (if tmp
  158.       (setq ents (append (xdrx_pickset->ents tmp) ents))
  159.     )
  160.     (xdrx_draworder->top
  161.       (setq ents (_clear (xd::list:removedup ents)))
  162.     )
  163.   )
  164.   (defun _clear (el)
  165.     (setq el (vl-remove nil
  166.                         (mapcar '(lambda (x)
  167.                                    (if (and x (entget x))
  168.                                      x
  169.                                    )
  170.                                  )
  171.                                 el
  172.                         )
  173.              )
  174.     )
  175.     (xdrx_polyline_compress el t)
  176.     el
  177.   )
  178.   (xdrx_begin)
  179.   (xdrx-sysvar-push '("dimzin" 0))
  180.   (if (not #xd_var_global_lw_width)
  181.     (setq #xd_var_global_lw_width 1.0)
  182.   )
  183.   (if (not #xd_var_global_ent_color)
  184.     (setq #xd_var_global_ent_color 7)
  185.   )
  186.   (setq m_rec_ent nil
  187.         xdir      (getvar "ucsxdir")
  188.   )
  189.   (xdrx_initssget
  190.     "\nSelect to add an existing rectangle to be processed <no selection>:"
  191.   )
  192.   (setq ss (xdrx_ssget '((0 . "LWPOLYLINE") (-4 . "&=") (70 . 1))))
  193.   (setq ents     (xdrx_pickset->ents ss)
  194.         ents-bak ents
  195.   )
  196.   (setq num 0)
  197.   (while
  198.     (and
  199.       (xd::doc:setosnap 547)
  200.       (if (> num 0)
  201.         (progn (setq info1 "/fallback(U)")
  202.                (xdrx_initget "A W C U S")
  203.         )
  204.         (progn (setq info1 "") (xdrx_initget "A W C S"))
  205.       )
  206.       (setq info
  207.              (strcat
  208.                "\nFirst point of rectangle [set axis (A)/width (W)/color (C)/set step size (S)"
  209.                info1
  210.                "]<Exit>:"
  211.              )
  212.       )
  213.       (xdrx_prompt
  214.         "\nCurrent setting: line width("
  215.         #xd_var_global_lw_width
  216.         ") color("
  217.         #xd_var_global_ent_color
  218.         ") Step("
  219.         (xdrx-getvar "distancesnap")
  220.         ")"
  221.       )
  222.       (setq p1 (getpoint info))
  223.       (cond ((= p1 "W")
  224.              (if (setq val (getreal (xdrx_prompt
  225.                                       "\nEnter Line width<"
  226.                                       #xd_var_global_lw_width
  227.                                       ">:"
  228.                                       t
  229.                                     )
  230.                            )
  231.                  )
  232.                (progn (setq #xd_var_global_lw_width val)
  233.                       (xdrx_entity_setproperty
  234.                         ents
  235.                         "constantwidth"
  236.                         #xd_var_global_lw_width
  237.                       )
  238.                )
  239.              )
  240.              t
  241.             )
  242.             ((= p1 "S")
  243.              (if (setq v (getint (xdrx-prompt
  244.                                    "\nInput Step Size<"
  245.                                    (xdrx-getvar "distancesnap")
  246.                                    ">:"
  247.                                    t
  248.                                  )
  249.                          )
  250.                  )
  251.                (xdrx-setvar "DistanceSnap" (abs v))
  252.              )
  253.              t
  254.             )
  255.             ((= p1 "C")
  256.              (setq #xd_var_global_ent_color
  257.                     (acad_colordlg
  258.                       #xd_var_global_ent_color
  259.                     )
  260.              )
  261.              (xdrx_entity_setproperty
  262.                ents
  263.                "color"
  264.                #xd_var_global_ent_color
  265.              )
  266.              t
  267.             )
  268.             ((= p1 "U")
  269.              (if (/= num 0)
  270.                (progn
  271.                  (vl-cmdf "undo" 2)
  272.                  (setq num (1- num))
  273.                  (setq ents (_clear ents-bak))
  274.                  (if (= num 0)
  275.                    (princ "\rAll operations have been rolled back!")
  276.                  )
  277.                )
  278.              )
  279.              t
  280.             )
  281.             ((= p1 "A")
  282.              (if (and (setq
  283.                         p_1 (getpoint "\nFirst point of axis <exit>:")
  284.                       )
  285.                       (setq
  286.                         p_2 (getpoint p_1
  287.                                       "\nSecond point of axis <exit>:"
  288.                             )
  289.                       )
  290.                  )
  291.                (progn (setq xdir (xdrx_vector_normalize
  292.                                    (mapcar '-
  293.                                            (trans p_2 1 0)
  294.                                            (trans p_1 1 0)
  295.                                    )
  296.                                  )
  297.                             xdir (if (minusp (car xdir))
  298.                                    (setq xdir (xdrx_vector_negate xdir))
  299.                                    xdir
  300.                                  )
  301.                       )
  302.                )
  303.              )
  304.              t
  305.             )
  306.             ((= (type p1) 'LIST) t)
  307.       )
  308.       (progn
  309.         (if (= (type p1) 'LIST)
  310.           (progn
  311.             (setq basept (trans p1 1 0))
  312.             (XD::Drag:CallBackSetMouseMove "_callback")
  313.             (setq tf t)
  314.             (while (and tf
  315.                         (setq txt1 (xdrx-text-make)
  316.                               txt2 (xdrx-text-make)
  317.                         )
  318.                         (xd::doc:setkeyword "A S D F G")
  319.                         (_prompt1)
  320.                         (setq p2
  321.                                (xd::doc:getcorner
  322.                                  p1
  323.                                  "\rThe second point of the rectangle [Step0(A)/Step1(S)/step5(D)/Step10(F)/Set(G)]<Exit>:"
  324.                                  7
  325.                                  xdir
  326.                                )
  327.                         )
  328.                    )
  329.               (cond ((= p2 "A") (xdrx-setvar "DistanceSnap" 0.0))
  330.                     ((= p2 "S") (xdrx-setvar "DistanceSnap" 1.0))
  331.                     ((= p2 "D") (xdrx-setvar "DistanceSnap" 5.0))
  332.                     ((= p2 "F") (xdrx-setvar "DistanceSnap" 10.0))
  333.                     ((= p2 "G")
  334.                      (if (setq
  335.                            v (getreal (xdrx-prompt
  336.                                         "\nEnter Step Size<"
  337.                                         (xdrx-getvar "distancesnap")
  338.                                         ">:"
  339.                                         t
  340.                                       )
  341.                              )
  342.                          )
  343.                        (xdrx-setvar "DistanceSnap" (abs v))
  344.                      )
  345.                     )
  346.                     ((and (= (type p2) 'LIST)
  347.                           (> (abs (xdrx_points_area (cadr p2))) 0.0)
  348.                      )
  349.                      (xdrx_undostart)
  350.                      (setq e1 (xdrx_polyline_make
  351.                                 (xd::pnts:ucs2wcs (cadr p2))
  352.                                 t
  353.                               )
  354.                      )
  355.                      (foreach n ents (_process e1 n))
  356.                      (setq num (1+ num))
  357.                      (setq ents     (cons e1 ents)
  358.                            ents-bak (cons e1 ents-bak)
  359.                            ents     (_clear ents)
  360.                      )
  361.                      (xdrx_entity_setproperty
  362.                        ents
  363.                        "constantwidth"
  364.                        #xd_var_global_lw_width
  365.                        "color"
  366.                        #xd_var_global_ent_color
  367.                       )
  368.                      (xdrx_undoend)
  369.                      (setq e1 nil)
  370.                      (setq tf nil)
  371.                     )
  372.               )
  373.               (xdrx-free txt1 txt2)
  374.             )
  375.           )
  376.         )
  377.         t
  378.       )
  379.     )
  380.   )
  381.   (xdrx_sysvar_pop)
  382.   (xdrx_end)
  383.   (princ)
  384. )
« Last Edit: December 13, 2023, 04:09:24 PM by xdcad »
The code I wrote uses XDRX-API,which can be downloaded from github.com and is updated at any time.
===================================
[XDrx-Sub Forum]
https://www.theswamp.org/index.php?board=78.0
https://github.com/xdcad/XDrx-API
http://bbs.xdcad.net

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2132
  • class keyThumper<T>:ILazy<T>
Re: [XDrX-PlugIn(41)] Feel free to do whatever you want" -- Free Rectang
« Reply #1 on: December 13, 2023, 07:24:58 PM »

Nice code and result !
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

ribarm

  • Gator
  • Posts: 3264
  • Marko Ribar, architect
Re: [XDrX-PlugIn(41)] Feel free to do whatever you want" -- Free Rectang
« Reply #2 on: December 13, 2023, 11:53:55 PM »
Code - Auto/Visual Lisp: [Select]
  1. ;Total boundary
  2. ;Stefan M. 09.01.2014
  3. ;Modified by M.R. 26.06.2018
  4. ;Modified by M.R. 24.05.2021 (replaced (initcommandversion) with (setvar 'qaflags 1))
  5. (defun c:TOTBNDR ( / *error* bb acDoc cmde qaf bbpts i lst ms r1 reg ss obj reg1 el ll ell ii y ch )
  6.  
  7.  
  8.   (defun *error* ( m )
  9.     (if cmde
  10.       (setvar 'cmdecho cmde)
  11.     )
  12.     (if qaf
  13.       (setvar 'qaflags qaf)
  14.     )
  15.     (if m
  16.       (prompt m)
  17.     )
  18.     (vla-endundomark acDoc)
  19.     (princ)
  20.   )
  21.  
  22.   (defun bb ( ss / mat i e minbb maxbb minbbl maxbbl p1 p2 )
  23.  
  24.  
  25.     (defun mat ( from to )
  26.       (list
  27.         (list (car (trans '(1.0 0.0 0.0) from to t)) (car (trans '(0.0 1.0 0.0) from to t)) (car (trans '(0.0 0.0 1.0) from to t)) (car (trans '(0.0 0.0 0.0) from to)))
  28.         (list (cadr (trans '(1.0 0.0 0.0) from to t)) (cadr (trans '(0.0 1.0 0.0) from to t)) (cadr (trans '(0.0 0.0 1.0) from to t)) (cadr (trans '(0.0 0.0 0.0) from to)))
  29.         (list (caddr (trans '(1.0 0.0 0.0) from to t)) (caddr (trans '(0.0 1.0 0.0) from to t)) (caddr (trans '(0.0 0.0 1.0) from to t)) (caddr (trans '(0.0 0.0 0.0) from to)))
  30.         (list 0.0 0.0 0.0 1.0)
  31.       )
  32.     )
  33.  
  34.     (repeat (setq i (sslength ss))
  35.       (setq e (ssname ss (setq i (1- i))))
  36.       (vla-transformby (vlax-ename->vla-object e) (vlax-tmatrix (mat 0 1)))
  37.       (vla-getboundingbox (vlax-ename->vla-object e) 'minbb 'maxbb)
  38.       (mapcar 'set '(minbb maxbb) (mapcar 'safearray-value (list minbb maxbb)))
  39.       (setq minbbl (cons minbb minbbl) maxbbl (cons maxbb maxbbl))
  40.       (vla-transformby (vlax-ename->vla-object e) (vlax-tmatrix (mat 1 0)))
  41.     )
  42.     (setq p1 (apply 'mapcar (cons 'min minbbl)) p2 (apply 'mapcar (cons 'max maxbbl)))
  43.     (setq p1 (list (if (equal (car p1) 0.0 1e-8) 0.0 (car p1)) (if (equal (cadr p1) 0.0 1e-8) 0.0 (cadr p1)) (if (equal (caddr p1) 0.0 1e-8) 0.0 (caddr p1))))
  44.     (setq p2 (list (if (equal (car p2) 0.0 1e-8) 0.0 (car p2)) (if (equal (cadr p2) 0.0 1e-8) 0.0 (cadr p2)) (if (equal (caddr p2) 0.0 1e-8) 0.0 (caddr p2))))
  45.     (list p1 p2)
  46.   )
  47.  
  48.   (setq ms (vlax-get acDoc (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace)))
  49.   (if (= 8 (logand 8 (getvar 'undoctl)))
  50.     (vla-endundomark acDoc)
  51.   )
  52.  
  53.   (while
  54.     (or
  55.       (prompt "\nSelect 2d curves in current UCS...")
  56.       (not (setq ss (ssget "_:L" '((0 . "*POLYLINE,CIRCLE,ELLIPSE,SPLINE,LINE,ARC,HELIX,REGION")))))
  57.       (not (and (equal (caddr (car (setq bbpts (bb ss)))) 0.0 1e-4) (equal (caddr (cadr bbpts)) 0.0 1e-4)))
  58.     )
  59.     (prompt "\nEmpty sel.set or selected curves not planar or planar but out of UCS...")
  60.   )
  61.  
  62.   (setq cmde (getvar 'cmdecho))
  63.   (setvar 'cmdecho 0)
  64.   (setq qaf (getvar 'qaflags))
  65.   (setvar 'qaflags 1)
  66.   (if ss
  67.     (progn
  68.       (repeat (setq i (sslength ss))
  69.         (setq i (1- i)
  70.               obj (vlax-ename->vla-object (ssname ss i))
  71.         )
  72.         (if
  73.           (eq (vla-get-ObjectName obj) "AcDbRegion")
  74.           (setq reg1 (cons obj reg1))
  75.           (setq lst  (cons obj lst))
  76.         )
  77.         (if
  78.           (eq (vla-get-ObjectName obj) "AcDbHelix")
  79.           (progn
  80.             (vla-put-height obj 0.0)
  81.             (vl-cmdf "_.UCS" "_W")
  82.             (setq el (entget (vlax-vla-object->ename obj)))
  83.             (vl-cmdf "_.UCS" "_M" "_non" (cdr (assoc 11 el)))
  84.             (vl-cmdf "_.UCS" "_ZA" "_non" '(0.0 0.0 0.0) "_non" (cdr (assoc 12 el)))
  85.             (setq ll el)
  86.             (mapcar '(lambda ( x ) (if (eq (car x) 10) (setq ell (cons (trans (cdr x) 0 1) ell)))) el)
  87.             (setq ell (reverse ell))
  88.             (setq ell (mapcar '(lambda ( x ) (trans (list (car x) (cadr x) 0.0) 1 0)) ell))
  89.             (setq ell (mapcar '(lambda ( x ) (list 10 (car x) (cadr x) (caddr x))) ell))
  90.             (setq el (member (assoc 10 el) el))
  91.             (setq ii -1)
  92.             (foreach x (reverse (cdr (reverse ell)))
  93.               (setq ii (1+ ii))
  94.               (setq y (nth ii el))
  95.               (setq ll (subst x y ll))
  96.             )
  97.             (entmod ll)
  98.             (setq ell nil)
  99.             (vl-cmdf "_.UCS" "_P")
  100.             (vl-cmdf "_.UCS" "_P")
  101.             (vl-cmdf "_.UCS" "_P")
  102.           )
  103.         )
  104.       )
  105.      
  106.       (if lst
  107.         (setq reg (vlax-invoke ms 'AddRegion lst))
  108.       )
  109.      
  110.       (setq reg (append reg reg1))
  111.       (if (setq r1 (car reg))
  112.         (progn
  113.           (foreach x (cdr reg) (vlax-invoke r1 'boolean acunion x))
  114.           (vl-cmdf "_.EXPLODE" (vlax-vla-object->ename r1))
  115.           (while (< 0 (getvar 'cmdactive))
  116.             (vl-cmdf "")
  117.           )
  118.           (if (not (vl-some '(lambda ( x ) (= (cdr (assoc 0 (entget x))) "REGION")) (vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget "_P"))))))
  119.             (vl-cmdf "_.UNDO" "1")
  120.             (setq reg (vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget "_P")))))
  121.           )
  122.         )
  123.       )
  124.  
  125.       (setq sss (ssadd))
  126.       (if (not (vlax-erased-p r1))
  127.         (progn
  128.           (setq el (entlast))
  129.           (vl-cmdf "_.EXPLODE" (vlax-vla-object->ename r1))
  130.           (while (< 0 (getvar 'cmdactive))
  131.             (vl-cmdf "")
  132.           )
  133.           ;(initcommandversion)
  134.           (vl-cmdf "_.JOIN" (ssget "_P"))
  135.           (while (< 0 (getvar 'cmdactive))
  136.             (vl-cmdf "")
  137.           )
  138.           (if (not (eq el (entlast)))
  139.             (while (setq el (entnext el))
  140.               (ssadd el sss)
  141.             )
  142.             (ssadd el sss)
  143.           )
  144.         )
  145.         (foreach r1 reg
  146.           (setq el (entlast))
  147.           (vl-cmdf "_.EXPLODE" r1)
  148.           (while (< 0 (getvar 'cmdactive))
  149.             (vl-cmdf "")
  150.           )
  151.           ;(initcommandversion)
  152.           (vl-cmdf "_.JOIN" (ssget "_P"))
  153.           (while (< 0 (getvar 'cmdactive))
  154.             (vl-cmdf "")
  155.           )
  156.           (if (not (eq el (entlast)))
  157.             (while (setq el (entnext el))
  158.               (ssadd el sss)
  159.             )
  160.             (ssadd el sss)
  161.           )
  162.         )
  163.       )
  164.     )
  165.   )
  166.   (initget "Yes No")
  167.   (setq ch (getkword "\nDo you want to delete selected entities and only leave total boundary [Yes/No] <Yes> : "))
  168.   (if (or (null ch) (= ch "Yes"))
  169.     (vl-cmdf "_.ERASE" ss "")
  170.   )
  171.   (prompt "\nSelection set stored in variable \"sss\" - it is highlighted... You can call it with !sss...")
  172.   (sssetfirst nil sss)
  173.   (*error* nil)
  174. )
  175.  
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube