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()
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.
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.
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)
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)
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)
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)
Civil engineer interested in automation in core subjects such as civil, mechanical and electrical, using IT skills comprising cloud computing, devops, programming languages and databases along with the technical skills gained while working as a civil engineer since past 3 years.
21 comments
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
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!
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.
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.
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 🙂
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)
regarding 3
You should try to use the Python dir() function to peak available methods and properties of an AutoCAD object. And check https://help.autodesk.com/view/OARX/2022/ENU/?guid=GUID-93DB8D09-11E2-4F80-8622-903BEC06B08A
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-
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)
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.”)
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!
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?
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?