TheSwamp

Code Red => .NET => Topic started by: sinc on August 07, 2010, 11:52:17 AM

Title: Walking a DGN Reference
Post by: sinc on August 07, 2010, 11:52:17 AM
Does anyone know how DgnReference items work?  I can't seem to find much info in the API, and searching the web hasn't turned anything up, either.

It looks like a DgnReference has a Transform object, much like blocks, so I think that part looks simple enough.  But from there, I get lost.  How would I, for example, get to the ObjectIds of the objects in the DgnReference?  It looks like the DgnReference.DefinitionId can be used to get to the DgnDefinition...  That might be part of it.  But I can't figure out how to use that DgnDefinition to get to the objects in the DGN.
Title: Re: Walking a DGN Reference
Post by: LE3 on August 07, 2010, 03:16:54 PM
Hi Sinc,

I found this url link, no idea if can be of some help for you, they have several code samples:

http://www.la-solutions.co.uk/content/publications-MVBA.htm

maybe...

Title: Re: Walking a DGN Reference
Post by: kaefer on January 02, 2011, 08:10:07 PM
[...] How would I, for example, get to the ObjectIds of the objects in the DgnReference?  It looks like the DgnReference.DefinitionId can be used to get to the DgnDefinition...  That might be part of it.  But I can't figure out how to use that DgnDefinition to get to the objects in the DGN.

Me neither. Poking around, i.e. selecting nested entities interactively, reveals that the Underlay is actually held in a separate Database.

While there aren't any exposed members accessible from the Underlay paraphernalia, this Database can also be obtained by listening to the DatabaseConstructed event, which fires when an Underlay is attached. This should suffice for automatic processing, while the manual approach with an existing Underlay would require the selection of a nested entity.

Demo in F#; asks for a DGN file name (as string), attaches it, captures the database and prints type and handle of all objects in its ModelSpace.

Code: [Select]
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.Runtime

type acApp = Autodesk.AutoCAD.ApplicationServices.Application

let dgnAttach dgnSourceFile =
    if System.IO.File.Exists dgnSourceFile then
        let dgnName = SymbolUtilityServices.GetSymbolNameFromPathName(dgnSourceFile, "*")

        let db = acApp.DocumentManager.MdiActiveDocument.Database
        use tr = db.TransactionManager.StartTransaction()
        let nod = tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite) :?> DBDictionary
        let defDictKey = UnderlayDefinition.GetDictionaryKey(typeof<DgnDefinition>)

        if not(nod.Contains defDictKey) then
            let dict = new DBDictionary()
            nod.SetAt(defDictKey, dict) |> ignore
            tr.AddNewlyCreatedDBObject(dict, true)
 
        let dgnDict = tr.GetObject(nod.GetAt(defDictKey), OpenMode.ForWrite) :?> DBDictionary
        let dgnDef = new DgnDefinition(SourceFileName = dgnSourceFile)
        let dgnDefId = dgnDict.SetAt(dgnName, dgnDef)                   
        tr.AddNewlyCreatedDBObject(dgnDef, true)

        let btr = tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId db, OpenMode.ForWrite) :?> BlockTableRecord
        let dgnRef = new DgnReference(DefinitionId = dgnDefId)
        btr.AppendEntity dgnRef |> ignore
        tr.AddNewlyCreatedDBObject(dgnRef, true)
                   
        tr.Commit()
    else
        raise <| new System.IO.FileNotFoundException(dgnSourceFile)

let mutable newDb = None

let databaseConstructedHandler =
    new System.EventHandler(
        fun sender _ -> newDb <- Some(sender :?> Database) )
 
[<CommandMethod "MyDgnAttach">]
let myDgnAttachCmd() =
    let doc = acApp.DocumentManager.MdiActiveDocument
    let ed = doc.Editor
    let pstrr = ed.GetString("\nDGN file to attach: ")
    if pstrr.Status = PromptStatus.OK then
        Database.DatabaseConstructed.AddHandler databaseConstructedHandler
        dgnAttach pstrr.StringResult
        Database.DatabaseConstructed.RemoveHandler databaseConstructedHandler

        if newDb.IsSome then
            let dbx = newDb.Value
            use tr = dbx.TransactionManager.StartTransaction()
            let btrId = SymbolUtilityServices.GetBlockModelSpaceId dbx
            let btr = tr.GetObject(btrId, OpenMode.ForRead) :?> BlockTableRecord
            for oid in btr do
                let dbo = tr.GetObject(oid, OpenMode.ForRead)
                ed.WriteMessage(
                    "\n{0} {1} ",
                    dbo.GetType(),
                    string dbo.Handle )
            tr.Commit()

Cheers, Thorsten
Title: Re: Walking a DGN Reference
Post by: mohnston on January 05, 2011, 12:35:24 PM
There are DGN libraries available from http://www.opendesign.com/the_oda_platform/tg (http://www.opendesign.com/the_oda_platform/tg)
I haven't worked with them.