Readdwgfile and Civil 3D Surfaces

Hi …
Looks like a conflict between AutoCAD Database Services and Civil Database Services.
The line
surf = id.GetObject(OpenMode.ForRead)
to access the Surface object by it’s object id is not correct, results in error …

NullReferenceException : Object reference not set to an instance of an object.
at Autodesk.AutoCAD.DatabaseServices.ObjectId.GetObject(OpenMode mode)

    with adoc.LockDocument():
        with Database(False, True) as db:
            db.ReadDwgFile(path, FileShare.ReadWrite, False, "")
            cdoc = CivilDocument.GetCivilDocument(db)
            sids = cdoc.GetSurfaceIds()
            for id in sids:
                surf = id.GetObject(OpenMode.ForRead)

just-surf.dyn (13.9 KB)
1.DWG (1.6 MB)

Locking the Autocad document is not required when you are side loading a DWG as the database.
You’re not inside a transaction - this is a requirement to get objects, after loading the DWG start the transaction manager.
using the id.GetObject() method outside of a transaction will not be very stable. It’s safer to use t.GetObject(id, OpenMode.ForRead) inside the transaction.
Is it possible that there are no surface ids? You could check with if sids.Count > 0:
And, as always, commit your transaction at the end

I was hoping to avoid using a transaction - but … it’s not possible … will redo the code today and try again … Thx Mike - your input is always highly appreciated.

1 Like

Thx Mike … this is working…


import os
import sys
import clr
from System.IO import FileShare  

clr.AddReference('AcMgd')
clr.AddReference('AcCoreMgd')
clr.AddReference('AcDbMgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AeccDbMgd')

from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

adoc = Application.DocumentManager.MdiActiveDocument

fset = IN[0]
o = []

def dwgtask (path):
    if not os.path.exists(path):
        return False
    adoc = Application.DocumentManager.MdiActiveDocument
    if adoc is None:
        return False
    with Database(False, True) as db:
        db.ReadDwgFile(path, FileShare.ReadWrite, False, "")
        cdoc = CivilDocument.GetCivilDocument(db)
        sids = cdoc.GetSurfaceIds()
        for id in sids:
            with db.TransactionManager.StartTransaction() as t:
                surf = t.GetObject(id,OpenMode.ForRead)
                o.append([path,surf.Name])
                t.Commit()
        db.CloseInput(True)
    HostApplicationServices.WorkingDatabase = adoc.Database
    return True


for f in fset:
    if not os.path.exists(f):
        continue
    dwgtask(f)

HostApplicationServices.WorkingDatabase = adoc.Database


OUT = o
1 Like