Tuesday, October 3, 2023

Python for AutoCAD performance pt2

 

While playing with win32com, I noticed there’s a function to generate a cache:

        acad = win32com.client.gencache.EnsureDispatch("AutoCAD.Application")

 This function made a huge difference with both an and out or process, worthy of a post, this is out of process, see the times in the code comments


import pythoncom
import win32com.client
from timeit import default_timer as timer

def comMatrix3d(mat):
        return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, mat)
   
start = timer()
comMat = comMatrix3d(
    [[1.0, 0.0, 0.0, 100.0],
     [0.0, 1.0, 0.0, 100.0],
     [0.0, 0.0, 1.0, 0.0],
     [0.0, 0.0, 0.0, 1.0]])

#166.88979500000278 without cache
#acad = win32com.client.Dispatch("AutoCAD.Application")

#40.01999249999972 with cache
acad = win32com.client.gencache.EnsureDispatch("AutoCAD.Application")
model = acad.ActiveDocument.ModelSpace

for ent in model:
    if ent.ObjectName == "AcDbPoint":
        ent.TransformBy(comMat)
       
end = timer()
print(end - start)



 and in process  

#import
import PyRx as Rx
import PyGe as Ge
import PyGi as Gi
import PyDb as Db
import PyAp as Ap
import PyEd as Ed
import traceback
from timeit import default_timer as timer

import win32com.client
import pythoncom

def comMatrix3d(mat : Ge.Matrix3d):
        return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, mat)
   
# 7.853941000001214 seconds
def PyRxCmd_doitcom():
    try:
        start = timer()
       
        comMat = comMatrix3d(
                [[1.0, 0.0, 0.0, 100.0],
                [0.0, 1.0, 0.0, 100.0],
                [0.0, 0.0, 1.0, 0.0],
                [0.0, 0.0, 0.0, 1.0]])
       
        # 7.853941000001214 seconds
        # this will use the cache if its found, in this case
        # the performance is the same as below
        #acad = win32com.client.Dispatch("AutoCAD.Application")
       
        #1.0649678999998287
        acad = win32com.client.gencache.EnsureDispatch("AutoCAD.Application")
        model = acad.ActiveDocument.ModelSpace
       
        for ent in model:
            if ent.ObjectName == "AcDbPoint":
                ent.TransformBy(comMat)
               
        end = timer()
        print(end - start)
       
    except Exception as err:
        traceback.print_exception(err)


# 0.219937599998957 seconds
def PyRxCmd_doitpyrx():
    try:
        start = timer()
        mat = Ge.Matrix3d()
        mat.setToTranslation(Ge.Point3d(100,100,0).asVector())
       
        db = Db.HostApplicationServices().workingDatabase()
        model =  Db.BlockTableRecord(db.modelSpaceId(), Db.OpenMode.kForRead)
 
        for id in model.objectIds(Db.Point.desc()):
            ent = Db.Entity(id, Db.OpenMode.ForWrite)
            ent.transformBy(mat)
           
        end = timer()
        print(end - start)
       
    except Exception as err:
        print(err)


No comments:

Post a Comment

TraceBoundary sample in Python for AutoCAD

    import traceback from pyrx_imp import Rx from pyrx_imp import Ge from pyrx_imp import Gi from pyrx_imp import Db from pyrx_imp...