Author Topic: Flex Duct Creator  (Read 71256 times)

0 Members and 1 Guest are viewing this topic.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Flex Duct Creator
« on: October 05, 2007, 06:21:32 PM »
Bored today so I created this routine. I still have a few issues with tight curves and abrupt changes in direction.
Perhaps some will try it out & report any other anomalies. Or any wish list items.

Thanks.

New Version 2.0  - Added Locked layer trap & CL change option .
Code: [Select]
;;;=======================[ FlexDuct.lsp ]==============================
;;; Author: Copyright© 2010 Charles Alan Butler (CAB)
;;; Contact or Updates  @  www.TheSwamp.org
;;; Version:  2.0   Mar 25,2010
;;; Purpose: Create Flex Duct from a centerline that the user picks
;;;    Centerline may be anything vla-curve will handle
;;; Sub_Routines:     
;;;    makePline which creates a LW Polyline
;;; Restrictions: UCS is supported
;;;    Duct Layer is hard coded, see var Flexlayer
;;;    Debug only error handler at this time
;;; Known Issues:
;;;    Tight curves cause pline jacket distortion
;;;    Added warning when this is about to occur
;;; Returns:  none
;;;=====================================================================
;;;   THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED     ;
;;;   WARRANTY.  ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR  ;
;;;   PURPOSE AND OF MERCHANTABILITY ARE HEREBY DISCLAIMED.            ;
;;;                                                                    ;
;;;  You are hereby granted permission to use, copy and modify this    ;
;;;  software without charge, provided you do so exclusively for       ;
;;;  your own use or for use by others in your organization in the     ;
;;;  performance of their normal duties, and provided further that     ;
;;;  the above copyright notice appears in all copies and both that    ;
;;;  copyright notice and the limited warranty and restricted rights   ;
;;;  notice below appear in all supporting documentation.              ;
;;;=====================================================================

(defun c:Flex (/         cl-ent    ribWidth  RibShort  RibLong   collar
               dist      steps     ribFlag   pt        curAng    curDer
               RibPtLst1 RibPtLst2 p1        p2        doc       space
               cflag     cl-len    ribRadius tmp       NewPline  NewPline2
               pl1       pl2       cnt       errflag   InsulThick   FlexColor
               FlexLayer ss        FlexCLLayer   lyrent *error*
              )
  (defun *error* (msg) (vl-bt))
  (vl-load-com)
  (setq Doc (vla-get-activedocument (vlax-get-acad-object)))
  (vla-endundomark doc)
  (vla-startundomark doc)

  ;; \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
 
  ;;  Change these if you want
 
  (setq FlexLayer "0")   ; put your Duct layer here
  (setq FlexColor acred) ; put your color over ride here or Bylayer
  (setq FlexCLLayer "xx");"0") ; put your Duct Center Line layer here, "" or nil = no change
  (setq InsulThick 0)    ; to be added to duct diameter, use 2 for 1" insulation
  (setq collar 4.0)      ; collar length at each end
  (setq DelCL nil)       ; delete the centerline t=Yes nil=No
  (setq GroupFlex nil)   ; make flex duct a Group t=Yes nil=No
 
  ;; \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/


  ;;   --------   Local Functions   ---------

  ;;  Expects pts to be a list of 2D or 3D points
  (defun makePline (spc pts)
    (if (= (length (car pts)) 2) ; 2d point list
      (setq pts (apply 'append pts))
      (setq
        pts (apply 'append (mapcar '(lambda (x) (list (car x) (cadr x))) pts))
      )
    )
    (setq
      pts (vlax-make-variant
            (vlax-safearray-fill
              (vlax-make-safearray vlax-vbdouble (cons 0 (1- (length pts))))
              pts
            )
          )
    )
    (vla-addlightweightpolyline spc pts)
  )
  ;;   -------------------------------------
  ;;  Does not work in ACAD 2000
  (defun _CreateAnonymousGroup ( ) ; courtesy of Michael Puckett
      (vla-add
          (vla-get-groups
              (vla-get-activedocument (vlax-get-acad-object)))  "*")
  )

  ;;  Get the Duct Diameter, global variable
  (or duct:dia (setq duct:dia 16.0)) ; default value
 
 
  ;;  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  ;;       S T A R T     H E R E   
  ;;  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  (while            ; Main Loop
    (progn
      (prompt (strcat "\nDuct diameter is set to "
                      (vl-princ-to-string duct:dia)
              )
      )
      (setvar "errno" 0) ; must pre set the errno to 0
      (initget "Diameter")
      (setq cl-ent
             (entsel (strcat "\nSelect center line of flex duct.[Diameter]<"
                             (vl-princ-to-string duct:dia)
                             "> Enter to quit."))
      )

      (cond
((null (setq lyrent (tblobjname "layer" Flexlayer)))
(prompt (strcat "\nDuct Layer " Flexlayer " does not exist."))
)
((= 4 (logand 4 (cdr (assoc 70 (entget lyrent)))))
(prompt (strcat "\nDuct Layer " Flexlayer " is LOCKED."))
        )
((and FlexCLlayer (/= FlexCLlayer "")
      (null (setq lyrent (tblobjname "layer" FlexCLlayer)))
      (princ (strcat "\n*** Center Line Layer " FlexCLlayer " does not exist. ***"))
      (setq FlexCLlayer nil))
)
        ((= (getvar "errno") 52) ; exit if user pressed ENTER
         nil        ; exit loop
        )
        ((= cl-ent "Diameter")
         (initget (+ 2 4))
         (setq
           tmp (getdist
                 (strcat "\nSpecify duct diameter <" (rtos duct:dia) ">: ")
               )
         )
         (and tmp (setq duct:dia tmp))
         t          ; stay in loop
        )

        ((vl-consp cl-ent)
         ;;  check entity before making the duct
         (if (not (vl-catch-all-error-p
                    (setq tmp (vl-catch-all-apply
                                'vlax-curve-getpointatparam
                                (list (car cl-ent) 0.0)
                              )
                    )
                  )
             )
           (progn   ; OK to make duct
             (setq cl-ent   (car cl-ent) ; Center Line
                   ribWidth (* duct:dia 0.167)
                   RibShort (+ duct:dia InsulThick) ; add insulation
                   RibLong  (+ RibShort (* ribWidth 2))
             )

             ;;  centerline length
             (setq cl-len (vlax-curve-getdistatparam
                            cl-ent
                            (vlax-curve-getendparam cl-ent)
                          )
                   steps  (/ cl-len ribWidth)
             )
             (if (= (logand (fix steps) 1) 1) ; T = odd
               (setq steps (fix steps))
               (setq steps (1+ (fix steps)))
             )
             (setq ribWidth (/ (- cl-len 0.25) (1- steps))
                   dist     0.125 ; distance along center line
             )

           
             (setq ribFlag 0
                   cflag   t
                   cnt     0
                   pl1     nil
                   pl3     nil
                   errflag nil
             )

             ;;  ----------   Create Rib End Points   -----------
             (repeat steps
               (setq pt (vlax-curve-getpointatdist cl-ent dist))
               ; (/ 1 0) debug - force error
               (setq
                 curDer (trans
                          (vlax-curve-getfirstderiv
                            cl-ent
                            (vlax-curve-getparamatpoint cl-ent pt)
                          )
                          0
                          1
                        )
               )
               ;; Get angle 90 deg to curve
               (setq curAng (+ (/ pi 2) (angle '(0 0) curDer)))
               (setq ribRadius (if (zerop ribFlag)
                                 (/ RibShort 2)
                                 (/ RibLong 2)
                               )
               )
               (setq pt (trans pt 0 1)) ; WCS > UCS
               (setq p1 (polar pt curAng ribRadius))
               (setq p2 (polar pt (+ pi curAng) ribRadius))
               (if cflag ; create start collar points
                 (setq RibPtLst1 (list (polar p1 (angle curDer '(0 0)) collar))
                       RibPtLst2 (list (polar p2 (angle curDer '(0 0)) collar))
                       cflag     nil
                 )
               )

               ;;  this collection method creates a woven pline
               (cond
                 ((null pl1) ; first time through
                  (setq RibPtLst1 (cons p1 RibPtLst1)
                        RibPtLst2 (cons p2 RibPtLst2)
                  )
                 )
                 ((= (logand (setq cnt (1+ cnt)) 1) 1) ; T = odd cnt
                  (setq RibPtLst1 (cons pl2 RibPtLst1)
                        RibPtLst1 (cons p2 RibPtLst1)
                        RibPtLst2 (cons pl1 RibPtLst2)
                        RibPtLst2 (cons p1 RibPtLst2)
                  )
                 )
                 ((setq RibPtLst1 (cons pl1 RibPtLst1)
                        RibPtLst1 (cons p1 RibPtLst1)
                        RibPtLst2 (cons pl2 RibPtLst2)
                        RibPtLst2 (cons p2 RibPtLst2)
                  )
                 )
               )
               (if (and pl3 (inters p1 p2 pl3 pl4 t))
                 (setq errflag t)
               )
               (setq ribFlag (- 1 ribFlag) ; toggle flag
                     dist    (+ ribWidth dist)
                     pl3     pl1
                     pl4     pl2
                     pl1     p1
                     pl2     p2
               )
             )
             ;;  create end collar points
             (setq RibPtLst1 (cons p2 RibPtLst1)
                   RibPtLst1 (cons (polar p2 (angle '(0 0) curDer) collar) RibPtLst1)
                   RibPtLst2 (cons p1 RibPtLst2)
                   RibPtLst2 (cons (polar p1 (angle '(0 0) curDer) collar) RibPtLst2)
             )

             ;;  --------   point list to WCS   ------------
             (setq RibPtLst1 (mapcar '(lambda (x) (trans x 1 0)) RibPtLst1))
             (setq RibPtLst2 (mapcar '(lambda (x) (trans x 1 0)) RibPtLst2))

             ;;  --------   create jacket plines   ------------
             (or space
                 (setq space
                        (if (zerop (vla-get-activespace doc))
                          (if (= (vla-get-mspace doc) :vlax-true)
                            (vla-get-modelspace doc) ; active VP
                            (vla-get-paperspace doc)
                          )
                          (vla-get-modelspace doc)
                        )
                 )
             )

             (cond
               ((and errflag
                     (progn
                       (initget "Yes No")
                       (= "No"
                          (cond
                            ((getkword "\nTurns too tight, Proceed? [Yes/No]<Yes>:"))
                            ("Yes")))
                       )
                     )
                t ; skip the create & stay in loop
               )
               ((setq newpline (makePline space RibPtLst1))
                (vla-put-layer newpline Flexlayer)
                (if FlexColor
                  (vla-put-color newpline FlexColor)
                )
                ;;(vla-put-elevation newpline z)

                (setq newpline2 (makePline space RibPtLst2))
                (vla-put-layer newpline2 Flexlayer)
                (if FlexColor
                  (vla-put-color newpline2 FlexColor)
                )
                ;;(vla-put-elevation newpline z)
               
                (if DelCL
  (entdel cl-ent) ; remove the centerline object
  (if (and FlexCLlayer (/= FlexCLlayer "")
   (setq lyrent (tblobjname "layer" (cdr(assoc 8 (entget cl-ent)))))
                           (or (/= 4 (logand 4 (cdr (assoc 70 (entget lyrent)))))
       (prompt "\n*** Center Line layer is LOCKED ***"))
              )
    (vla-put-layer (vlax-ename->vla-object cl-ent) FlexCLlayer)
  )
)
                ;| COMMAND method removed due to errors in ACAD2008
                (if GroupFlex
                  (progn
                    (setq ss (ssadd))
                    (ssadd (vlax-vla-object->ename newpline) ss)
                    (ssadd (vlax-vla-object->ename newpline2) ss)
                    (or DelCl (ssadd cl-ent ss))
                    (if (vl-cmdf "_.-group" "_create" "*" "" ss "")
                      (princ "\nGrouping Done")
                      (princ "\nError Grouping")
                    )
                  )
                )
                |;
                (if GroupFlex
                  (progn ; using Michael Puckett's method
                    (setq GroupObjects (list newpline newpline2))
                    (or DelCl (setq GroupObjects
                        (cons (vlax-ename->vla-object cl-ent) GroupObjects)))
                    (setq myGroup (_CreateAnonymousGroup))
                    (vlax-invoke myGroup 'AppendItems GroupObjects)
                   )
                 )

               )
             ) ; cond
           )        ; progn
           (princ "\nError - Can not use that object, Try again.")
         )          ; endif
         t
        )
        (t (princ "\nMissed Try again."))
      )             ; cond stmt
    )               ; progn
  )                 ; while
  (vla-endundomark doc)
  (and space (vlax-release-object space))
  (vlax-release-object doc)
  ;;-----------  E N D   O F   L I S P  ----------------------------
  (princ)
)
(prompt "\nFlex Duct loaded, Enter FLEX to run.")
(princ)



<edit: updated code>


« Last Edit: March 25, 2010, 10:42:13 AM 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.

deegeecees

  • Guest
Re: Flex Duct Creator
« Reply #1 on: October 05, 2007, 06:25:41 PM »
That's some nice work, new toys are always fun, thanks CAB!

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Flex Duct Creator
« Reply #2 on: October 05, 2007, 06:46:36 PM »
Thank you sir.

I revised the code fixing the jacket cross over problem, but the tight turns are still messing with me.
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.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Flex Duct Creator
« Reply #3 on: October 05, 2007, 06:49:25 PM »
If there is no radius (sharp corner) then just make the radius at the center the same as the duct width, or make the small side radius the same.  Looks pretty, but I haven't tested it yet.  Will soon though.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Flex Duct Creator
« Reply #4 on: October 05, 2007, 06:53:56 PM »
How about making each duct an anonymous block?
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Flex Duct Creator
« Reply #5 on: October 05, 2007, 07:32:23 PM »
Good idea Tim.

Off to prep dinner.  :angel:
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.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Flex Duct Creator
« Reply #6 on: October 05, 2007, 09:27:10 PM »
Changed the code.
New Version 1.1  - This version creates only 2 plines and no lines.
This is easier to erase.
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.

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
Re: Flex Duct Creator
« Reply #7 on: October 08, 2007, 09:17:25 AM »
Another awesome routine.

Thanks Cab.
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Flex Duct Creator
« Reply #8 on: October 08, 2007, 09:35:35 AM »
Glad you all like it.
I am considering Tim's suggestion for blocks and am testing some code gile helped me with to deal with OCS when there are not the same as the current UCS.
Currently the routine will deal with current UCS in most cases.
Stay tuned for updates.
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.

JohnK

  • Administrator
  • Seagull
  • Posts: 10623
Re: Flex Duct Creator
« Reply #9 on: October 08, 2007, 09:38:07 AM »
Wow, i will have to check this out when i get back into the office! Nice work CAB.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Flex Duct Creator
« Reply #10 on: October 08, 2007, 09:48:14 AM »
John, I forgot you were into HVAC. Let me know if you have any suggestions.
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.

LE

  • Guest
Re: Flex Duct Creator
« Reply #11 on: October 08, 2007, 09:59:05 AM »
Alan;

I tried your routine.... Te sacaste un 10! (A+) - those HVAC users will love it.... :)

JohnK

  • Administrator
  • Seagull
  • Posts: 10623
Re: Flex Duct Creator
« Reply #12 on: October 08, 2007, 10:08:35 AM »
John, I forgot you were into HVAC. Let me know if you have any suggestions.

You got it. I will put the thunkin' cap on when i try it.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
Re: Flex Duct Creator
« Reply #13 on: October 08, 2007, 10:12:31 AM »
Alan;

I tried your routine.... Te sacaste un 10! (A+) - those HVAC users will love it.... :)
After further review;
(I have been playing with it all morning and not getting much work done.)
From archie's point of view, I like it becuase it graphically looks like a duct for when I need to show a piece of duct for coordination purposes.  It stands out more than just two lines in a detail.  And it handles all the radii without any input from me.
The bonus is its simplicity in the way it is used.

Score = 10
Bonus points = 5
 :-)
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans

ronjonp

  • Needs a day job
  • Posts: 7527
Re: Flex Duct Creator
« Reply #14 on: October 08, 2007, 10:22:59 AM »
Nice CAB  :-)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC