Jump to content

How to work with closed drawing(s) in Python (ObjectDBX)


Recommended Posts

Posted (edited)

For these examples, I’ll be working with a folder with copies of the same drawing, pretend they’re floors of the same building or something

 

dwgset.png.d391ddd9f360f8c68505cfeace0ca98f.png

Edited by Danielm103
Posted (edited)

One thing to keep in mind, is that way python’s garbage collector works;

First created, First deleted. We want to break up the functions to ensure that the side database is not deleted before any of it’s objects.

This example, we will iterate though all eight files and count the number of phones by floor

 

import traceback
from pyrx import Db, Ed, Ge, Ap, Rx, Gs
from timeit import default_timer as timer
from collections import defaultdict


def processDWG(db: Db.Database, allphones: dict[int]):
    # scan the entire database for blocks, this is a tad slower than just scanning
    # modelspace
    refs = [Db.BlockReference(id) for id in db.objectIds(Db.BlockReference.desc())]
    for ref in refs:
        if ref.getBlockName() != "FNPHONE":
            continue
        allphones[db.getFilename()] += 1


def readDWG(file: str, allphones):
    # we reading an already created drawing, so change
    # buildDefaultDrawing: bool = False,
    # noDocument: bool = True
    # we want to keep this in a seperate function
    sideDb = Db.Database(False, True)
    sideDb.readDwgFile(file)
    sideDb.closeInput(True)
    processDWG(sideDb, allphones)


@Ap.Command()
def doit():
    try:
        start = timer()
        # read all text from a collection of drawings
        allphones = defaultdict(int)
        for file in Ap.Application.listFilesInPath("E:\\temp", ".dwg"):
            readDWG(file, allphones)

        print("Time = {} seconds: ".format(timer() - start))

        for k, v in allphones.items():
            print(k, v)

    except Exception as err:
        traceback.print_exception(err)

 

Command: DOIT
Time = 0.1402779999998529 seconds:
E:\temp\Floor Plan Sample1.dwg 51
E:\temp\Floor Plan Sample2.dwg 51
E:\temp\Floor Plan Sample3.dwg 51
E:\temp\Floor Plan Sample4.dwg 51
E:\temp\Floor Plan Sample5.dwg 51
E:\temp\Floor Plan Sample6.dwg 51
E:\temp\Floor Plan Sample7.dwg 51
E:\temp\Floor Plan Sample8.dwg 51

 

Edited by Danielm103
Posted

If you notice, everywhere a class or function returns an objectId collection, you can apply a type filter

refs = [Db.BlockReference(id) for id in db.objectIds(Db.BlockReference.desc())]
    

 

  • Danielm103 changed the title to How to work with closed drawing(s) in Python (ObjectDBX)
Posted

The working database

https://help.autodesk.com/view/OARX/2025/ENU/?guid=OARX-RefGuide-AcDbHostApplicationServices__workingDatabase

 

AcDbHostApplicationServices::workingDatabase

AcDbHostApplicationServices::setWorkingDatabase

 

It’s mostly legacy stuff at this point; there are some function calls in ObjectARX that do not have a database parameter. They work assuming that that the working database has been set.

This is the same sample as above, but we use AutoWorkingDatabase

 

import traceback
from pyrx import Db, Ed, Ge, Ap, Rx, Gs
from timeit import default_timer as timer
from collections import defaultdict


def processDWG(allphones: dict[int]):
    # shortcut to
    # Db.HostApplicationServices.workingDatabase()
    db = Db.workingDb()
    refs = [Db.BlockReference(id) for id in db.objectIds(Db.BlockReference.desc())]
    for ref in refs:
        if ref.getBlockName() != "FNPHONE":
            continue
        allphones[db.getFilename()] += 1


def readDWG(file: str, allphones):
    sideDb = Db.Database(False, True)
    sideDb.readDwgFile(file)
    sideDb.closeInput(True)

    # use RAII to set and restore the working db
    wdb = Db.AutoWorkingDatabase(sideDb)
    processDWG(allphones)


@Ap.Command()
def doit():
    try:
        start = timer()
        # read all text from a collection of drawings
        allphones = defaultdict(int)
        for file in Ap.Application.listFilesInPath("E:\\temp", ".dwg"):
            readDWG(file, allphones)

        print("Time = {} seconds: ".format(timer() - start))

        for k, v in allphones.items():
            print(k, v)

    except Exception as err:
        traceback.print_exception(err)

 

same output

Command: DOIT
Time = 0.12193889999980456 seconds:
E:\temp\Floor Plan Sample1.dwg 51
E:\temp\Floor Plan Sample2.dwg 51
E:\temp\Floor Plan Sample3.dwg 51
E:\temp\Floor Plan Sample4.dwg 51
E:\temp\Floor Plan Sample5.dwg 51
E:\temp\Floor Plan Sample6.dwg 51
E:\temp\Floor Plan Sample7.dwg 51
E:\temp\Floor Plan Sample8.dwg 51

 

Posted

Working with the layout manager in a side database context, LayoutManager methods have overloads that take a database argument

 

import traceback
from pyrx import Db, Ed, Ge, Ap, Rx, Gs
from timeit import default_timer as timer
from collections import defaultdict


def processDWG(db: Db.Database, allLayouts: dict[list]):
    
    lm = Db.LayoutManager()
    
    # LayoutManager methods have overloads that take a database argument
    # here we just want to get the layout names
    for layoutName, LayoutId in lm.getLayouts(db).items():
        allLayouts[db.getFilename()].append(layoutName)
        
        # example if we want to search for title blocks
        # ignore the model tab
        if not "MODEL".casefold() in layoutName.casefold():
            layout = Db.Layout(LayoutId)
            ps = Db.BlockTableRecord(layout.getBlockTableRecordId())
            for id in ps.objectIds(Db.BlockReference.desc()):
                ref = Db.BlockReference(id)
                print(ref.getBlockName())


def readDWG(file: str, allLayouts):
    sideDb = Db.Database(False, True)
    sideDb.readDwgFile(file)
    sideDb.closeInput(True)
    processDWG(sideDb, allLayouts)


@Ap.Command()
def doit():
    try:
        start = timer()
        allLayouts = defaultdict(list)
        for file in Ap.Application.listFilesInPath("E:\\temp", ".dwg"):
            readDWG(file, allLayouts)

        print("Time = {} seconds: ".format(timer() - start))

        for k, v in allLayouts.items():
            print(k, v)

    except Exception as err:
        traceback.print_exception(err)

 

Command: DOIT
Project data <--- a block I added to paperspace, could be a title block
Time = 0.0780531999989762 seconds:
E:\temp\Floor Plan Sample1.dwg ['Layout1', 'Model']
E:\temp\Floor Plan Sample2.dwg ['Layout1', 'Model']
E:\temp\Floor Plan Sample3.dwg ['Layout1', 'Model']
E:\temp\Floor Plan Sample4.dwg ['Layout1', 'Model']
E:\temp\Floor Plan Sample5.dwg ['Layout1', 'Model']
E:\temp\Floor Plan Sample6.dwg ['Layout1', 'Model']
E:\temp\Floor Plan Sample7.dwg ['Layout1', 'Model']
E:\temp\Floor Plan Sample8.dwg ['Layout1', 'Layout2', 'Model']

 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...