Making a square to circle duct transition.

Making a square to circle duct transition.

yashpn1805
Explorer Explorer
943 Views
9 Replies
Message 1 of 10

Making a square to circle duct transition.

yashpn1805
Explorer
Explorer
  • Currently I have a function in which the elevation (height or z coordinate) of polyline (square most of the time) and circle are compared and if they are in same elevation than gives error, and if not it runs a program called CONNVERTI.
  • In function CONNVERTI it ask user to select a circle and a polyline. After that it sets the number of segments circle will be divided into (which is 20).
  • A math calculation is set to start making points on circle with the increasing angle (from 0° to 360° so that it make points equal to number segments it has been set to).
  • After that connect two vertices of polyline to nearest quadrant (same with the other 3 quadrants connecting to nearest two vertices of polyline, and making a closed 3dpolyline surface will be make extrusion and it will not extrude if it's not a  made with closed surface with single line).  yashpn1805_0-1695065588018.png

     

  • The points which lies between two quadrants will be connect to the nearest vertex (same making closed surface single 3dpolyline).
    yashpn1805_1-1695065715079.pngyashpn1805_2-1695065739788.png

     

  • Once all surfaces are created the than just extrude all surface with 1/4 inch thickness.

    The code I did is:

    (defun c:S2CTRANS ()
     
      (setq circle (car (entsel "\nSelect a circle : "))) ; Select a circle
      (setq polyline (car (entsel "\nSelect a polyline: "))) ; Select a polyline
     
      (setq dxf-data1 (entget circle)) ; Get the DXF data of the circle
      (setq dxf-data2 (entget polyline)) ; Get the DXF data of the polyline
     
      (setq circleElevation (cdr (assoc 10 dxf-data1))) ; Extract the circle elevation
      (setq polylineElevation (cdr (assoc 38 dxf-data2))) ; Extract the polyline elevation
     
      (setq z1 (rtos (caddr circleElevation)))
      (setq z2 (rtos polylineElevation))
     
      (if (= z1 z2)
       
        (alert "\nObjects have the same Elevation.\n")
        (PROGN
          (prompt "\nObjects have different Elevation.\n")
          (C:CONNVERTI)
        )
      )
      (princ)
    )

    (defun CONNVERTI ()
      (setq polyline (car (entsel "\nSelect a polyline: "))) ; Select a polyline
      (setq circle (car (entsel "\nSelect a circle: "))) ; Select a circle

      (setq dxf-data (entget circle)) ; Get the DXF data of the circle
     
      (setq circleData (cdr (assoc 10 dxf-data))) ; Extract elevation value
      (setq radius (cdr (assoc 40 dxf-data))) ; Extract radius
     
      (setq center (list (nth 0 circleData) (nth 1 circleData)))
      (setq ele (nth 2 circleData))
     
      (setq numSegments 20) ; number of segments circle will be divided into.

       (setq angleIncrement (/ (* 2.0 pi) numSegments)) ; Calculate the angle increment
      (setq angle 0.0) ; Initialize the angle

      ; Create a list to store the 3D polyline points
      (setq polylinePoints '())

      ; ; ; Create segments by specifying the end points on the circle
      (repeat numSegments
        (setq x (cos angle))
        (setq y (sin angle))

        (setq endPoint (list (+ (car center) (* radius x))
                             (+ (cadr center) (* radius y)))) ; Calculate the endpoint
       
        (setq xP (car endPoint))
        (setq yP (cadr endPoint))
       
        (setq point-entity (entmake (list '(0 . "POINT")
                                        (cons 10 (list xP yP ele))
                                        (cons 8 "Layer1") ; Replace with your desired layer
        )))
       
        (setq polylinePoints (cons endPoint polylinePoints))
        (setq angle (+ angle angleIncrement)) ; Update the angle for the next segment
      )
     
      ; (setq particularPoint (car polylinePoints))
      ; (princ particularPoint)
      ; (setq xP (car particularPoint))
      ; (setq yP (cadr particularPoint))
     
      ; (setq point-entity (entmake (list '(0 . "POINT")
      ;                                  (cons 10 (list xP yP ele))
      ;                                  (cons 8 "Layer1") ; Replace with your desired layer
      ;                                )))

      (if (= polylineVertices numPoints)
        (progn
          (setq i 0)
          (repeat polylineVertices
            (setq pt1 (vlax-curve-getPointAtDist polyline i))
            (setq pt2 (nth i polylinePoints))
            (setq polylineToCirclePoints (cons pt1 polylineToCirclePoints))
            (setq polylineToCirclePoints (cons pt2 polylineToCirclePoints))
            (setq i (+ i 1))
          )
        )
        (progn
          (princ "The number of polyline vertices does not match the number of circle points.")
          (exit)
        )
      )

      ; Create the 3D polyline
      (setq polyline3D (vlax-invoke (vla-get-activedocument (vlax-get-acad-object)) 'Add3DPoly polylineToCirclePoints))

      (princ (strcat "Created a 3D polyline connecting the circle to the polyline."))
      (princ)
    )

    Thanks,
0 Likes
944 Views
9 Replies
Replies (9)
Message 2 of 10

yashpn1805
Explorer
Explorer

The code above is not working and giving error: bad argument type: VLA-OBJECT nil

Autocad file for reference:

0 Likes
Message 3 of 10

Sea-Haven
Mentor
Mentor

Pretty sure there is a lot of UNFOLD sheet metal programs out there, a Google should reveal, so get more shapes as a result.

 

One I found ANTARES high-end computing (ant-ares.de)

0 Likes
Message 4 of 10

paullimapa
Mentor
Mentor

There were a number of problems with your initial code. I modified it the best I could. You'll need to go back and adjust because with my modifications the 3dplines created look way too much (see attached dwg & lsp):

paullimapa_0-1695158218816.png

In Summary these were the major changes:

c:S2CTRANS:

Added localized variables & functions

Added CONNVERTI function into c:S2CTRANS

(defun c:S2CTRANS 
  ; localize variables & functions
  (/ circle circleElevation CONNVERTI 
     dxf-data1 dxf-data2
     polyline polylineElevation z1 z2
  )

Modified selection of circle & polyline to include filters:

;  (setq circle (car (entsel "\nSelect a circle : "))) ; Select a circle
; selection filter for circle
  (while (not circle) 
   (princ"\nSelect Circle...")
   (setq circle (ssget "_+.:E:S" '((0 . "CIRCLE"))))
  )
  (setq circle (ssname circle 0))
;  (setq polyline (car (entsel "\nSelect a polyline: "))) ; Select a polyline
; selection filter for closed lwpline
  (while (not polyline) 
   (princ"\nSelect Closed Pline...")
   (setq polyline (ssget "_+.:E:S" '((0 . "LWPOLYLINE")(-4 . "&")(70 . 1))))
  )
  (setq polyline (ssname polyline 0))

You don't have a function called (C:CONNVERTI) and instead of selecting circle & polyline again I included these are arguments passing them onto function (CONNVERTI)

    (PROGN
      (prompt "\nObjects have different Elevation.\n")
;      (C:CONNVERTI) ; this is not defined
      ; call CONNVERTI function passing circle & pline objects as arguments so don't need to select again
      (CONNVERTI circle polyline)
    )

Again localized variables in CONNVERTI sub function:

(defun CONNVERTI 
  ; localize variables & functions       
  (circle-arg polyline-arg
   /
   acadObj angleIncrement anglenum center circleData doc endPoint 
   dxf-data ele i numSegments 
   points point-entity polyline3D polylineToCirclePoints polylinePoints
   pt1 pt2 radius x y xP yP
  )

Never use variable matching name of built-in Autolisp function ie: angle:

  ; don't use function name as variable in this case angle is a built in autolisp function
;  (setq angle 0.0) ; Initialize the angle
  (setq anglenum 0.0) ; Initialize the angle

For endpoint I included circle's Z elevation "ele" so all point lists have x y & z:

    (setq endPoint (list (+ (car center) (* radius x))
                         (+ (cadr center) (* radius y))
                         ele                             ; include circle elevation as z
                   )
          
    ) ; Calculate the endpoint

 Then your code goes into a test of 2 variables which have yet to be defined so I took a guess here:

; code missing polylineVertices & numPoints
; perhaps these?
  (setq polylineVertices (length polylinePoints))
  (setq numPoints numSegments)
  
  (if (= polylineVertices numPoints)
    (progn

 Lastly I had to revised your entire section on creating the 3dpoly:

  ; Create the 3D polyline
;  (setq polyline3D (vlax-invoke (vla-get-activedocument (vlax-get-acad-object)) 'Add3DPoly polylineToCirclePoints))
; Add3DPoly Method (ActiveX)
; https://help.autodesk.com/view/OARX/2023/ENU/?guid=GUID-21D7283A-552F-4DD8-BB4D-AEA1632186B9
  (setq acadObj (vlax-get-acad-object))
  (setq doc (vla-get-ActiveDocument acadObj))
  (setq modelSpace (vla-get-ModelSpace doc))
; https://www.afralisp.net/archive/methods/list/add3dpoly_method.htm
  ; "dissolve" the points into atoms with append:
  (setq polylineToCirclePoints (apply 'append polylineToCirclePoints))
  ; If number of coordinates in point list is not
  ; a multiple of 3 then a lwpolyline can't be made.
  ; If it's a multiple of 3 then put the point
  ; list into an array and pass it on to Add3DPoly:
  (if (= (rem (length polylineToCirclePoints) 3) 0)
    (progn
     (setq points (vlax-make-safearray vlax-vbdouble (cons 0 (- (length polylineToCirclePoints) 1))))
     (vlax-safearray-fill points polylineToCirclePoints)
     (setq polyline3D (vla-Add3DPoly modelSpace points))
     (princ (strcat "Created a 3D polyline connecting the circle to the polyline."))
    )
    (princ "\nError: 3DPoly could not be created")
  )

Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 5 of 10

Sea-Haven
Mentor
Mentor

Puallimapa did you look at the link, the program looked very impressive. Have not tried it. Seemed way better than to try and reinvent the wheel.

0 Likes
Message 6 of 10

paullimapa
Mentor
Mentor

Since the OP had questions on what is causing code errors I decided to focus on that instead 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 7 of 10

smallƑish
Advocate
Advocate

@paullimapa 

Thats Amazing !! 

0 Likes
Message 8 of 10

paullimapa
Mentor
Mentor

Glad to have helped… cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 9 of 10

yashpn1805
Explorer
Explorer

Hello @paullimapa ,

I got to a point where I need to create a 3polyline (3dpolyline because the two points will be on certain elevation, like on square/rectangle, and third one on other elevation, on circle) connecting three pre-defined points and the line should be connecting those point in continuous way as it will be extruded in future, so if it's a closed surface made by continuous 3d polyline than it will extrude otherwise it will not.

0 Likes
Message 10 of 10

yashpn1805
Explorer
Explorer

Here is the code I have work on @paullimapa ,

(defun draw3DPolyline (point1 point2 point3)
  ; Create a list of the DXF codes and values for the 3D polyline
  (setq dxf-list (list '(0 . "POLYLINE") ; Entity type
                       '(100 . "AcDbEntity") ; Subclass marker
                       '(8 . "Layer1") ; Layer name (replace with your desired layer)
                       '(100 . "AcDb3dPolyline") ; Subclass marker
                       '(66 . 1) ; Vertices follow flag
                       '(10 0.0 0.0 0.0) ; Dummy point
                       '(70 . 8) ; Polyline flag (3D polyline)
                       '(0 . "VERTEX") ; Entity type
                       '(100 . "AcDbEntity") ; Subclass marker
                       '(8 . "Layer1") ; Layer name (same as polyline)
                       '(100 . "AcDb3dPolylineVertex") ; Subclass marker
                       (cons 10 point1) ; First vertex location
                       '(70 . 32) ; Vertex flag (3D vertex)
                       '(0 . "VERTEX") ; Entity type
                       '(100 . "AcDbEntity") ; Subclass marker
                       '(8 . "Layer1") ; Layer name (same as polyline)
                       '(100 . "AcDb3dPolylineVertex") ; Subclass marker
                       (cons 10 point2) ; Second vertex location
                       '(70 . 32) ; Vertex flag (3D vertex)
                       '(0 . "VERTEX") ; Entity type
                       '(100 . "AcDbEntity") ; Subclass marker
                       '(8 . "Layer1") ; Layer name (same as polyline)
                       '(100 . "AcDb3dPolylineVertex") ; Subclass marker
                       (cons 10 point3) ; Third vertex location
                       '(70 . 32) ; Vertex flag (3D vertex)
                       '(0 . "SEQEND") ; Entity type
                       '(100 . "AcDbEntity") ; Subclass marker
                       '(8 . "Layer1") ; Layer name (same as polyline)
  ))

  ; Create the 3D polyline entity from the DXF list
  (setq polyline-entity (entmake dxf-list))

  ; Return the entity name of the 3D polyline
  polyline-entity
)

 

; Connect 3 points to make triangle
  (setq point1 (getpoint))
  (setq point2 (getpoint))
  (setq point3 (getpoint))
 
  (draw3DPolyline point1 point2 point3)
0 Likes