Python Code to extrude a circle to a separate circle that is offset of the first circle.

Python Code to extrude a circle to a separate circle that is offset of the first circle.

sjelen
Contributor Contributor
717 Views
24 Replies
Message 1 of 25

Python Code to extrude a circle to a separate circle that is offset of the first circle.

sjelen
Contributor
Contributor

Good morning, everyone!

 

Is there a way to extrude or loft 1 circle to another circle to create a solid cylinder where the circles are drawn on the xz plane but are not directly inline with one another. Circle 1 lets say is at 10, 0 , 0 and Circle 2 is at 15, 20, 0. 

 

Does pyautocad have a function that will perform this extrusion? 

 

I have thought about maybe creating a point in the center of the circles and then creating a line between the two circles as a rail for the extrusion to follow. Would I even need to go that far? 

 

Thank you all for your time!

0 Likes
718 Views
24 Replies
Replies (24)
Message 2 of 25

Kent1Cooper
Consultant
Consultant

I may not understand correctly, but it sounds like a job for ordinary LOFT.  If that doesn't do what you want, please explain in detail, and post a small drawing with Circles in the kind of relationship you have.

Kent Cooper, AIA
0 Likes
Message 3 of 25

sjelen
Contributor
Contributor

Hey Kent, thanks for responding. What's the proper syntax for lofting using pyautocad? Is there one? I cannot get it to work. 

0 Likes
Message 4 of 25

Kent1Cooper
Consultant
Consultant

[Sorry, but I don't know pyautocad.  I don't see a Forum about it in the Autodesk world, but could there be one in the Python world?]

Kent Cooper, AIA
0 Likes
Message 5 of 25

DGCSCAD
Collaborator
Collaborator

There is a dedicated Python section over at theswamp.org.

AutoCad 2018 (full)
Win 11 Pro
Message 6 of 25

sjelen
Contributor
Contributor

Great, thank you! I'll check that out. 

0 Likes
Message 7 of 25

sjelen
Contributor
Contributor

No problem, thanks Kent. Do you think I could do the same process with the AutoLisp language? I tried but could not figure out how to make it more automated. When I would run the code, it would ask me to choose the circles and the line, which defeated the purpose of trying to save time and have it automatically create the loft. 

0 Likes
Message 8 of 25

Kent1Cooper
Consultant
Consultant

@sjelen wrote:

.... Do you think I could do the same process with the AutoLisp language? .... 


Surely that's possible, and it should not require your center points or line -- just selection of the two Circles.  Can you post a sample drawing?

Kent Cooper, AIA
0 Likes
Message 9 of 25

Sea-Haven
Mentor
Mentor

This is just using Extrude and Subtract is it that what your looking for done manually but could be a lisp.

SeaHaven_0-1749169758696.png

 

0 Likes
Message 10 of 25

daniel_cadext
Advisor
Advisor

For pyautocad or com, you can usually search and follow along what’s in the VBA docs. For PyRx you can ask at the swamp or in the github discussions. For PyRx, you can usually get what you need from VBA, .NET or ARX documentation

 

Here’s a sample in PyRx. Note: in pyautocad, you don’t have geometry classes, but you may be able to use numpy to compute vectors

import traceback
from pyrx import Ap, Ax, Ge


@Ap.Command()
def xdoit() -> None:
    try:
        axApp = Ap.Application.acadApplication()
        axDoc = axApp.activeDocument()
        axModel = axDoc.modelSpace()

        # maybe use numpy to compute the vector
        direction = Ge.Point3d(15, 20, 0) - Ge.Point3d(10, 0, 0)

        # create the circle
        circle = axModel.addCircle(Ge.Point3d(10, 0, 0), 5)

        # set the normal to the extrution direction
        circle.setNormal(direction)

        # create a region to extrude
        regions = axModel.addRegion([circle])

        solid = axModel.addExtrudedSolid(regions[0], direction.length(), 0.0)

        circle.erase()

    except Exception as err:
        traceback.print_exception(err)

extrude.png

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 11 of 25

sjelen
Contributor
Contributor

This is what I'm going for. I have a CSV file of points that I would like to eventually draw circles at the points and then loft the circles from the points that coincide with one another.

 Lofting pic1.png

0 Likes
Message 12 of 25

Kent1Cooper
Consultant
Consultant

AutoLisp can do that, this way for those values [in simplest terms]:

(defun C:TEST (/ c1)
  (command "_.circle" '(0 0 0) 1)
  (setq c1 (entlast))
  (command
    "_.circle" '(3 1 -30) 1
    "_.loft" c1 (entlast) "" ""
  ); command
  (prin1)
)

Instead of having the values built in, it would presumably need to include the opening of your CSV file, and reading of centers and radii from there to use in the commands, and closing of the file.  If you have a sample file, the command can be adjusted to accommodate the format of the information.  [Just one pair of locations per file, or multiples?  How exactly are the coordinates expressed in the text content?  Is there anything like a header line to bypass?  Is perhaps the radius always the same with only the locations in the file?  Etc.]

Kent Cooper, AIA
0 Likes
Message 13 of 25

sjelen
Contributor
Contributor

The CSV file comes from the total station lay out from the field engineer. 

point number - y - x - z and have a coordinate for each plane and the point number we set on the total station. 

 

The code would just reference the CSV and not be implemented in the code?

 

No, the CSV file would have hundreds of points, but each point would have a "pair" and that's where the circles and lofting would occur. Yes, all the circles will be the same radius.

 

I've attached a test CSV file of what it would be like. the .1 would be the partner point. ex. 100 and 100.1 would be together. We can always change the point name if needed. Also apologies I thought I recalled it being xyz and instead it is yxz. 

 

0 Likes
Message 14 of 25

daniel_cadext
Advisor
Advisor

maybe something like this?

 

from pyrx import Ap, Db, Ge, Db, Ap, Ed, Ax, command
import csv

@command
def doit():
    axApp = Ap.Application.acadApplication()
    axDoc = axApp.activeDocument()
    axModel = axDoc.modelSpace()
    
    #read the points
    pnts = []
    with open("e:\\temp\\APL-Export.csv", "r") as f:
        for i, line in enumerate(csv.reader(f, delimiter=",")):
            if i == 0:
                continue
            pnts.append(Ge.Point3d(float(line[2]), float(line[1]), float(line[3])))
            
    if len(pnts) < 2:
        return
    
    # start direction
    direction = pnts[1] - pnts[0] 
    circle = axModel.addCircle(pnts[0], 1)
    circle.setNormal(direction)
    regions = axModel.addRegion([circle])
    
    #create a path
    path = axModel.add3DPoly(pnts)
    solid = axModel.addExtrudedSolidAlongPath(regions[0], path)

extrude2.png

 

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 15 of 25

Sea-Haven
Mentor
Mentor

There is no reason why the description could not be a pipe diameter, if blank use a default value, also with descriptions can have a look up function and draw on correct layer. 

 

Back to task  I am not sure that using loft draws the correct object, I may be wrong don't play with 3dsolids enough, if you have an inclined pipe ie different xyz then the circle needs to be draw at 90 to the line direction, ie at an angle when viewed in plan, then using extrude and path or a UCS with height option and  will draw correct pipe between 2 Z's. Now where is that 3dline angle stuff. 

 

The left image is a loft of 2 circles the right is a circle rotated to match line direction. Note thickness also.

 

SeaHaven_0-1749261795554.png

 

 

0 Likes
Message 16 of 25

sjelen
Contributor
Contributor

Hey Daniel, thanks for this. I like where you’re going but I would not want them all connected like that. Each pair would be an individual cylinder. 

I believe you mentioned in a different conversation that this is written in C++? 

Would you be able to guide me to a site or two where I can better understand that information. I am fairly new to python but I don’t know anything about C++ and have dabbled in AutoLisp for a different project.

Thank you! 

0 Likes
Message 17 of 25

sjelen
Contributor
Contributor

Hey Sea-Haven, thanks for looking into this for me. Am I understanding correctly that you’re saying in the description portion of the CSV I could add a comment to where the code would perform the function that way? 

ok over to your other point about the circles not being 90 degrees to the line it’s following. That is ok for me. I’m not as concerned with the ends as I am the cylinder shape itself. That’s where I thought loft worked for my scenario as when I use loft in Fusion it makes the solid from 2 points regardless of the orientation, or adding a “rail” will make it follow that path. What’s critical for me will be a consistent cylinder size. 

if it helps I’m trying to use this to replicate rebar in a concrete slab. Once I figure out the cylinders in one direction I’ll want to create another set perpendicular to the first set, replicating top bar and bottom bar.

 

thank you again for your help! 

0 Likes
Message 18 of 25

daniel_cadext
Advisor
Advisor

" Each pair would be an individual cylinder"

You can use the same algorithm and split the data up to pairs.

 

" written in C++?"

Don’t worry about the C++ stuff, I was just trying to explain the difference between pyautocad and pyrx, the interfaces from a scripter’s perspective are both python

you might try both and see which is more comfortable to program in

 

The link to the project is in my signature, there’s discussions and samples, and there’s also more samples over at the swamp

~Dan

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 19 of 25

Sea-Haven
Mentor
Mentor

Give this a try and use the csv provided as it has radius set. Else set radius to a fixed value in csv.

 

; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/python-code-to-extrude-a-circle-to-a-separate-circle-that-is/td-p/13667896
; drawtubes by AlanH June 2025
; reads two xyz points and radius in a csv file

; thanks to Lee-mac for this defun
(defun C:dotubes ( / oldsnap oldaunits csv fo str x1 x2 y1 y2 z1 z2 rad)
(defun csv->lst (str del / pos )
(if (setq pos (vl-string-position del str))
    (cons (substr str 1 pos) (csv->lst (substr str (+ pos 2)) del))
    (list str)
    )
)

(defun tube (ent rad / obj start end len)
(setq obj (vlax-ename->vla-object ent))
(setq start (vlax-curve-getstartPoint obj))
(setq end (vlax-curve-getEndPoint obj))
(setq len (vlax-get obj 'length))
(command "UCS" "3" start end "")
(command "circle" "0,0,0" rad)
(setq ent2 (entlast))
(command "rotate3d" ent2 "" "Y" "0,0,0" (/ pi 2.))
(command "extrude" ent2 "" len)
(command "UCS" "W")
(princ)
)

;;starts here

(setq oldsnap (getvar 'osmode))
(setvar 'osmode 0)
(setq oldaunits (getvar 'aunits))
(setvar 'aunits 3)

(setq csv (getfiled "Select CSV File" "" "csv" 16))
(setq fo (open csv "R"))
(setq str (read-line fo))

(while (setq str (read-line fo))
  (setq lst (csv->lst str 44))
  (setq x1 (atof (nth 1 lst)) y1 (atof (nth 2 lst))  z1 (atof (nth 3 lst)) rad (atof (nth 4 lst)))
  (setq str (read-line fo))
  (setq lst (csv->lst str 44))
  (setq x2 (atof (nth 1 lst)) y2 (atof (nth 2 lst)) z2 (atof (nth 3 lst)))
  (command "line" (list x1 y1 z1)(list x2 y2 z2) "")
  (tube (entlast) rad)
)

(CLOSE FO)
(command "zoom" "e")
(setvar 'aunits oldaunits)
(setvar 'osmode oldsnap)
(princ)
)
(c:dotubes)

SeaHaven_0-1749455517347.png

 

0 Likes
Message 20 of 25

sjelen
Contributor
Contributor

DANG! That worked really nice! Thank you Lee-Mac and Alan! 

 

I do like how using the description can be used to dictate the diameter of the cylinder. If it's rebar or PT we could specify a different diameter that way in the description so that's great! 

 

I'm having a hard time rotating the plane so that the elements are drawn and extruded along the XZ plane and not the XY plane. I'd like to draw the circles on the XZ and extrude along the XY plane. I thought I could change the USC you have but that isn't working. 

 

This is really coming together though! Really exciting!

Thank you again! 

sjelen_0-1749664011618.png

 

0 Likes