AutoCAD object operations with pyautocad

In this blog post I will introduce some very common AutoCAD operations and how we can implement them in a Python script using pyautocad. We will discuss how to copy, move/paste, delete, rotate, offset, scale and highlight objects.

Setting up Python script and AutoCAD model

First of all, we will set up our work environment for performing actions on the AutoCAD template using Python’s pyautocad module.

from pyautocad import Autocad, APoint, aDouble
from math import *

acad = Autocad(create_if_not_exists=True)

Adding AutoCAD objects to drawing template using pyautocad in Python

As we have already discussed from our previous blogs in this pyautocad series about creating objects, we will draw some objects to perform the operations on them as mentioned above.

c1 = acad.model.AddCircle(APoint(100, 100, 0), 100)
l1 = acad.model.AddLine(APoint(100,100), APoint(300, 350))
el1 = acad.model.AddEllipse(APoint(250, 300), APoint(700, 450), 0.5)

So, we have created a circle, a line, and an ellipse.

We will zoom into the created objects using the “ZoomExtents” method. This command works same as the default “zoom all” command in AutoCAD.

acad.app.ZoomExtents()
Figure 1: Practice objects

Using copy, move and delete methods for basic AutoCAD operations

As we have sketched the basic AutoCAD objects, we will start with three of the most used commands i.e. copy, move, and delete.

The way copy work while using pyautocad is, we can create a copy of an existing object, store that in a variable and use the “Move” method to paste it at the desired location.

c2 = c1.Copy()

#obj.Move(previous location, new location)
c2.Move(APoint(100, 100), APoint(300, 300))

Here, we are copying the “c1″ circle and storing the replica of that in the variable”c2”. Then, we are copying it from its existing center point i.e. (100, 100, 0) to (300, 300, 0) by using the “Move” method.

Figure 2.1: Copied circle c1 to c2

As you can see from Figures 1 and 2, we have copied circle 1 to a new location. Now, if we do not want our previous circle “c1”, we can Delete it; else we could have moved the circle “c1” using the Move method instead of copying it.

Let’s delete the circle “c1” now.

Figure 2.2: Deleted circle c1

Rotate AutoCAD objects with pyautocad in Python

Now, we will discuss how to rotate objects. Here, we will copy line l1 and will rotate the same from its existing base point (100, 100, 0) to 90 degrees.

l2 = l1.Copy()

# obj.Rotate(Base point, Angle of rotation)
l2.Rotate(APoint(100,100), pi*90/180)
Figure 3: Rotated line l1 to l2

Offsets objects in AutoCAD using pyautocad

Now, lets discuss how to take offsets of any object. We will need the Offset method to use against the object we want that offset for.

Here, we will take offset for the existing ellipse i.e. “el1”.

el2 = el1.Offset(10)
Figure 4: Offset of ellipse el1

Scaling AutoCAD objects in Python

To scale an object up or down we will need the “Offset” method to be used against the object we want to scale.

Let’s scale down the existing circle “c2”.

# obj.ScaleEntity(Base point, Scaling factor)
c3 = c2.ScaleEntity(APoint(300, 300), 0.5)
Figure 5.1: Scaled down circle c2

In case, we have many objects to deal with, we can highlight the specific object using the “Highlight” method and pass the parameter as “True”.

l2.Highlight(True)  
Figure 5.2: Highlighted line l2

You May Also Like

Leave a Reply

21 comments

Wei Lin says:

Dear Tanmay Sawant

Thank you for the writtings.

When I use offset for an ellipse as below:

el1 = acad.model.AddEllipse(APoint(0, 0), APoint(28, 0), 0.5)
el2 = el1.Offset(1.5)

Though it works on autocad, el2 cannot be defined. error message as below:

Traceback (most recent call last):

File “”, line 2, in
el2 = el1.Offset(1.5)

File “C:\anaconda\lib\site-packages\comtypes\client\lazybind.py”, line 182, in caller
return self._comobj._invoke(descr.memid, descr.invkind, 0, *args)

File “C:\anaconda\lib\site-packages\comtypes\automation.py”, line 730, in _invoke
return var._get_value(dynamic=True)

File “C:\anaconda\lib\site-packages\comtypes\automation.py”, line 457, in _get_value
typ = _vartype_to_ctype[self.vt & ~VT_ARRAY]

KeyError: 9

Could you kindly check whether the “Offset” method works as the tutorial? Thank you very much.

Best regards

Tekoha says:

I got the same error, you can try this:

try:
el2 = el1.Offset(5)
except KeyError:
None

Tekoha,

This kind of error handling is in general not recommended, since you catch the error but you dont handle / resolve it. That way the program will run even though it actually throws exceptions.

We will get back to this question (Tanmay and myself).

Hello,

You can use the code given below which won’t fetch any error:


import win32com
from win32com.client import *
import pythoncom

acad = win32com.client.Dispatch(“AutoCAD.Application”)
acadModel = acad.ActiveDocument.ModelSpace #Works same as acad.model

def APoint(x, y, z = 0):
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))

def ADouble(*argv):
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (argv))

c1 = acadModel.AddCircle(APoint(0, 0, 0), 15)
c2 = c1.Offset(2)
print(c2)
print(c2[0])

Thanks, have a great day!

James Goldman says:

Hi there Linnart, this is James Goldman. I replied to your video on YouTube and you told me to redirect my question here.

Is it possible to select an existing object (group of lines and circles etc) from an existing Autocad folder? I intend to make some changes to an existing Autocad folder, and move some existing 2D objects around. I understand that there are functions to move objects around (as shown in this video), but these objects seem to be ones which have been created in a new Autocad folder, just wondering if it’s possible for existing objects in an existing folder. Thanks so much! Really appreciate the advice.

James says:

Hi Linnart,

This is James, I commented on your YouTube post, asking a question and you asked me to redirect it here. My apologies, as I accidentally deleted the YouTube comment while I was attempting to copy and paste the question here. My question is:
Is there a function to select existing objects in existing Autocad files (made up of existing lines/circles etc). I want to make changes to a current Autocad file using pyautocad. I understand that there are functions (eg copy/move/offset) for new lines/circles created in a new Autocad file, but I’m wondering if the same can be done for objects in an existing Autocad file. Hence is there a way to select these existing objects, like maybe a function to select all objects within a specific 2D space?

Thanks so much for the help! Really appreciate it.
Best regards,
James

Hi Mr. Goldman,

Thanks for your question.

You can import the objects from the existing drawing by implementing the Import method on the AutoCAD document.

Open the drawing in which you want to Import the objects. Then use the below-mentioned code with the required parameters:

acad.doc.Import(“Full path of the file from which you want to import the objects”, Insertion Point in your current drawing where you want to insert those objects Using aDouble, scale factor)

But in this case the entire drawing will be exported from the previous drawing to his one and not any specific objects.

Though, I will come up with a solution to import specific objects soon.

Kind regards.

James says:

Hi Tanmay,

Thanks so much for your prompt reply. After importing all the objects from that file, I was wondering if there was any pyautocad function which enables me to select/define specific objects (groups of lines/circles etc) as I intend to move/delete these objects. The only issue I have is with this selection/defining of the existing objects, as I am unable to use the move/offset/mirror functions if I do not define them, like in the case of a new Autocad folder, where I am define a new line, and am able to move/offset it after as I can “call” it by its defined name. Thanks for your kind help!

Best regards,
James

Dear Mr Goldman,

Thank you for your question. Getting back to you soon. Please also see my other comment 🙂

teko says:

Hi Tanmay & Linnart,
After trying to use pyautocad, i have few questions:
1. if i want to make a line with a certain angle and length, it means i have to create a line using , L = acad.model.AddLine(Apoint(x1, y1), APoint(x2, y2)) and then use L.Rotate(origin, angle).
Is there any shorter way to do this?
in the AddLine method, can we use angle, starting point and length, such as in the AutoCAD?
2. The offset method such as in this webpage, is not clear to me how to define the direction, for example, to offset a line to the left or right direction (above or under).
3. I couldn’t find the answers to these problems in your documentation.
Maybe I missed it. Please let me know if you can point me to the correct documentation.
Because from the example, usually not enough, we have to know what other parameter/feature is not shown in the example. There is no docstring when I do `acad.model.AddLine?` or when i use help(…).
Thank you very much for this library.
best,
Teko

regarding 1.

import math
from pyautocad import Autocad, APoint
acad = Autocad(create_if_not_exists=True)
start_point = APoint(0, 0)
length = 100
angle_degrees = 30
angle_radians = math.radians(angle_degrees)
end_point = APoint(start_point.x + length * math.cos(angle_radians), start_point.y + length * math.sin(angle_radians))
line = acad.model.AddLine(start_point, end_point)

regarding 2

import math
from pyautocad import Autocad, APoint, AVector

acad = Autocad(create_if_not_exists=True)

start_point = APoint(0, 0)
end_point = APoint(100, 0)

line = acad.model.AddLine(start_point, end_point)

line_vector = AVector(end_point.x – start_point.x, end_point.y – start_point.y, 0)
normal_vector = line_vector.rotate(math.pi / 2, AVector(0, 0, 1))

offset_line = line.Offset(start_point, normal_vector, -10)

teko says:

Hi Linnart,

Thanks a lot for all of your answer.
regarding 1: exactly what I have done as well. So there is no kwarg “angle”. just to make sure.
regarding2: thank you.
regarding3: could you elaborate more, if possible one simple example of how to do it? Thank you very much.
great library!
-teko-

Deepak says:

Can we change the normal of a circle? or can we draw a circle in XZ place?

regarding drawing cicle in xz plane instead of xy:
import pyautocad
acad = pyautocad.Autocad()
center = pyautocad.APoint(10, 0, 10)
radius = 5
circle = acad.model.AddCircle(center, radius)

Ashish Ranjan says:

hello,
I am trying to connect with Autocad 23 using pyautocad with the below provided code but it gives the error:
OSError: [WinError -2147221005] Invalid class string
Code:-
from pyautocad import Autocad

acad = Autocad(create_if_not_exists=True)

try:
acad.zoom_extents()
print(“AutoCAD connection successful.”)
except:
print(“Failed to connect to AutoCAD.”)

Lam says:

Dear Tanmay Sawant!
I used the Attribute “OFFSET”, and I want all the object OFFSET OUTSIDE (Bigger). But some of my Shapes them become OFFSET INSIDE(Smaller).
Please tell me, How can I fix that problem? or How can I Reverse these Shapes?
Thank you so much!

Anne Mary says:

Hi Tanmay & Linnart,
After trying to use pyautocad, i have few questions:
1. I was trying to find the point of intersection between a offset line and another line, Using intersections = line1.IntersectWith(line2,0) , where line2 is an offset created. But this is returning a error.
Thank you very much for this library.
Best Regards,
Anne

Hi Anne. We are not the authors of the library 🙂 What is the error message?

Ross says:

Hi Linnart,

I have a couple of questions that have been bugging me for a while and I hope you can help.

1)is there a way to ask the user to pick a point and then store the point coordinates in python to manipulate or provide a specific name?
2)is there a way to manipulate the UCS so that i can draw on a specific plane?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.