While working with autocad we cannot ignore arrays as it is the most integral part of AutoCAD utilities. There are two types of arrays in pyautocad, one being rectangular and the other is polar. In this blog post, we are going to discuss the rectangular array.
Setting up the environment
Before moving forward I will set up our work environment by importing the pyautocad library. This integrates Python with AutoCAD.
from pyautocad import Autocad, APoint, aDouble
from math import *
acad = Autocad(create_if_not_exists=True)
Creating an object
To create an array I will draw a rectangle using the AddPolyline method to use it as a base object.
sqp = aDouble(50, 150, 0, 50, 550, 0, 850, 550, 0, 850, 150, 0, 50, 150, 0)
sq1 = acad.model.AddPolyline(sqp)
Working with the ArrayRectangular method
Now I will create a rectangular array. But before creating the same I explain how pyautocad creates the rectangular array based on the parameters that we pass on to the respective method.
Let us check out the syntax of the ArrayRectangular method:
# Syntax:
object.ArrayRectangular(NumberOfRows, NumberOfColumns, NumberOfLevels, DistBetweenRows, DistBetweenColumns, DistBetweenLevels)
Levels are 3D parameters. We use that to create layers of array along z axis. We set NumberOfLevels parameter to 1 always as we need to create the array on x, y plane.
The object in the selection set is assumed to be in the lower left-hand corner, and the array is generated up and to the right when the object is created.
For instance, let’s create an array from the rectangle we have already created.
arr1 = sq1.ArrayRectangular(5, 5, 1, 100, 100, 0)
As we can see from Figure 2, the command parameters row distance (100 units) and column distance (100 units) were used by pyautocad by considering the lower-left corner of the rectangle as base points to create the array.
But, we are not expecting this. We need to create an array having 100 as the distance between the boundaries of two objects.
Creating array using boundaries as base
Now, we will write a simple code to use the boundaries of objects as a base for creating array offsets for the rectangle.
def array_rectangle(x, y, z, r, c, lr, dr, dc, dl):
l=int(input("Enter length of rectangle:"))
w=int(input("Enter width of rectangle:"))
rect = (x, y, z, x, y+w, z, x+l, y+w, z, x+l, y, z, x, y, z)
rec = acad.model.AddPolyline(aDouble(rect))
arr = rec.ArrayRectangular(r, c, lr, dr+w, dc+l, dl)
In this code, we have to pass x, y, z coordinates as the base point for creating the rectangle. After that we will add the same set of parameters as mentioned in the command syntax.
Now, let us see how the array gets created after passing parameters in this code.
array_rectangle(50, 150, 0, 3, 3, 1, 150, 250, 0)
Array of circle
Let us try drawing an array for a circle using the existing command.
c = acad.model.AddCircle(APoint(100, 100), 100)
arr = c.ArrayRectangular(3, 3, 1, 50, 50, 0)
Now, we will write a simple code to create an array of circles to consider the boundaries of the circle as a base.
def array_circle(x, y, rad, r, c, lr, dr, dc, dl):
c1 = acad.model.AddCircle(APoint(x, y), rad)
arr2 = c1.ArrayRectangular(r, c, lr, dr+rad*2, dc+rad*2, dl)
array_circle(100, 100, 100, 3, 3, 1, 50, 100, 0)
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.
12 comments
Dear Tanmay,
I don’t understand why is returned this error when I use the method ArrayRectangle.
Thank you
Regards,
Edoardo
start=APoint(1000.00, 1036.64, 0.00)
Ri=100
Nx=40
Ny=23
DistBetweenRows=450
DistBetweenColumns=779.42
CircleObj1 = acad.model.AddCircle(start, Ri)
arr = CircleObj1.ArrayRectangular(Nx, Ny, 1, DistBetweenRows, DistBetweenColumns, 0)
Traceback (most recent call last):
File “”, line 2, in
arr = CircleObj1.ArrayRectangular(Nx, Ny, 1, DistBetweenRows, DistBetweenColumns, 0)
File “C:\Python37\lib\site-packages\comtypes\client\lazybind.py”, line 182, in caller
return self._comobj._invoke(descr.memid, descr.invkind, 0, *args)
File “C:\Python37\lib\site-packages\comtypes\automation.py”, line 730, in _invoke
return var._get_value(dynamic=True)
File “C:\Python37\lib\site-packages\comtypes\automation.py”, line 457, in _get_value
typ = _vartype_to_ctype[self.vt & ~VT_ARRAY]
KeyError: 9
Dear Edoardo,
Thanks for your question. I would like to know, which python version is being used over here. Can you please update the same if it is 3.7 or anything older than that? This sometimes happens with older versions of python while working with some random commands.
Else please check if the version of package comtypes is a latest one, otherwise use:
pip install comtypes
I would like to know if this helps you.
Have a nice day!
Hi Tanmay,
thank you for the quick reply.
The python version is Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:58:18)
Comtypes is c:\python37\lib\site-packages (1.1.10)
So, do you suggest to install a more recent version of python?
Thank you
Cheers
Edoardo
Hi,
Yes, if possible, please try using the latest version of Python. Also, check if the comtypes package installed is updated too, as it is a dependency for pyautocad.
Thank you!
Hi,
sorry to bother you again.
I’ve just checked with
Python 3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03)
comtypes-1.1.10 pyautocad-0.2.0
but it returns the same error.
And unfortunately I can’t install newer ver of python because they need Win 10, I don’t have it.
I will try an alternative way.
Thank you
Have a nice day
Edo
Hi Edoardo,
No issues at all, please find the script below, this has to work.:
import win32com.client
import pythoncom
from math import pi
acad = win32com.client.Dispatch(“AutoCAD.Application”)
acadModel = acad.ActiveDocument.ModelSpace
def APoint(x, y, z = 0):
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))
def ADouble(xyz):
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (xyz))
def aVariant(vObject):
return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, (vObject))
c1 = acadModel.AddCircle(APoint(1000.00, 1036.64, 0.00), 100)
c1.ArrayRectangular(Nx, Ny, 1, DistBetweenRows, DistBetweenColumns, 0)
—————————————————————————–
Always happy to help 🙂
Have a great day.
I have written code where I have to hatch between pavement, shoulders and ground. I mean I have to select multiple polylines but it is surely a closed object. I have tried this code but it does not work.
I have already imported APoint and aDouble from pyautocad. If I redefine these, it will create a duplicate. Anyhow I am beginner. Its my second day using pyautocad.
Looking forward to find answer.
P.S
I am getting the following error.
my aVariant contains:
win32com.client.VARIANT(8201, [, , , , , , , , ])
While the Error msg:
(-2147352567, ‘Exception occurred.’, (‘Invalid input’, ‘AutoCAD.Application’, ‘C:\\Program Files\\AutoCAD 2008\\HELP\\OLE_ERR.CHM’, -2145386493, None))
Hi Kareemi,
Thanks for your question.
Please refer our blog on hatching objects:
https://www.supplychaindataanalytics.com/hatching-objects-on-autocad-template-using-pywin32-python/
Have a great day!
Dear Tanmay,
when I use method ArrayRectangle, It returns following error:
I appreciate if you could help me with that
def array_rectangle(x, y, z, r, c, lr, dr, dc, dl):
l = float(input(“Enter width of rectangle:”))
w = float(input(“Enter length of rectangle:”))
rect = (x, y, z, x, y + w, z, x + l, y + w, z, x + l, y, z, x, y, z)
rec = acad.model.AddPolyline(aDouble(rect))
m = rec.ArrayRectangular(r, c, lr, dr + w, dc + l, dl)
array_rectangle(-0.375, -2, 0, 1, 1, 1, 0, 0, 0)
—————————————————————————————-
Traceback (most recent call last):
File “C:\Users\amirz\AppData\Local\Programs\Python\Python39\lib\code.py”, line 90, in runcode
exec(code, self.locals)
File “”, line 1, in
File “C:\Program Files\JetBrains\PyCharm 2022.2.3\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py”, line 198, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File “C:\Program Files\JetBrains\PyCharm 2022.2.3\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py”, line 18, in execfile
exec(compile(contents+”\n”, file, ‘exec’), glob, loc)
File “C:\Users\amirz\PycharmProjects\ProjectCAD_Alantum\Pyautocad.py”, line 39, in
array_rectangle(-0.375, -2, 0, 1, 1, 1, 0, 0, 0)
File “C:\Users\amirz\PycharmProjects\ProjectCAD_Alantum\Pyautocad.py”, line 35, in array_rectangle
m = rec.ArrayRectangular(r, c, lr, dr + w, dc + l, dl)
File “C:\Users\amirz\OneDrive\Desktop\Alantum\Project CAD\lib\site-packages\comtypes\client\lazybind.py”, line 182, in caller
return self._comobj._invoke(descr.memid, descr.invkind, 0, *args)
File “C:\Users\amirz\OneDrive\Desktop\Alantum\Project CAD\lib\site-packages\comtypes\automation.py”, line 747, in _invoke
return var._get_value(dynamic=True)
File “C:\Users\amirz\OneDrive\Desktop\Alantum\Project CAD\lib\site-packages\comtypes\automation.py”, line 467, in _get_value
typ = _vartype_to_ctype[self.vt & ~VT_ARRAY]
KeyError: 9
Hello,
I would appreciate if you could tell me how I can get objects for individual rectangles I create using ArrayRectangular function
Hi amir,
Could you please elaborate what exactly you want?